@aipack-ai/cli 0.0.2 → 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.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  main
4
- } from "./chunk-LXRCYMRS.js";
4
+ } from "./chunk-TPMRQPLX.js";
5
5
 
6
6
  // src/bin.ts
7
7
  main(process.argv.slice(2)).then((code) => process.exit(code)).catch((err) => {
@@ -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: "0.0.2",
8
+ version: "1.0.0",
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",
@@ -25,8 +25,9 @@ var package_default = {
25
25
  ],
26
26
  scripts: {
27
27
  build: "tsup",
28
- prebuild: "pnpm --filter @aipack-ai/agent build",
28
+ prebuild: "[ -f ../agent/dist/index.d.ts ] || pnpm --filter @aipack-ai/agent build",
29
29
  typecheck: "tsc --noEmit",
30
+ test: "node --import tsx --test test/*.test.ts",
30
31
  dev: "tsx src/bin.ts"
31
32
  },
32
33
  keywords: [
@@ -42,6 +43,7 @@ var package_default = {
42
43
  },
43
44
  dependencies: {
44
45
  "@aipack-ai/agent": "workspace:*",
46
+ "@aipack-ai/compression": "workspace:*",
45
47
  chalk: "^5.3.0"
46
48
  },
47
49
  devDependencies: {
@@ -134,6 +136,10 @@ function parseArgs(args) {
134
136
  result.noTools = true;
135
137
  } else if (arg === "--safe") {
136
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];
137
143
  } else if (arg === "--print" || arg === "-p") {
138
144
  result.print = true;
139
145
  const next = args[i + 1];
@@ -198,11 +204,13 @@ ${"\u5DE5\u5177\u9009\u9879:"}
198
204
  --no-tools, -nt \u7981\u7528\u5168\u90E8\u5DE5\u5177
199
205
  --safe \u4FDD\u5B88\u6A21\u5F0F\uFF1A\u5199\u6587\u4EF6/shell \u5168\u90E8\u4EBA\u5DE5\u786E\u8BA4
200
206
 
201
- \u5185\u7F6E\u5DE5\u5177: read, write, edit, bash
207
+ \u5185\u7F6E\u5DE5\u5177: read, write, edit, bash, find, grep, ls
202
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
203
209
  \uFF08sudo\u3001rm -rf ~\u3001\u78C1\u76D8\u5199\u5165\u3001\u8FDC\u7A0B\u811A\u672C\u7BA1\u9053\u7B49\uFF09\u9700\u786E\u8BA4
204
210
 
205
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
206
214
  --system-prompt <\u6587\u672C> \u66FF\u6362\u9ED8\u8BA4\u7CFB\u7EDF\u63D0\u793A\u8BCD
207
215
  --append-system-prompt <\u6587\u672C> \u8FFD\u52A0\u7CFB\u7EDF\u63D0\u793A\u8BCD\uFF08\u53EF\u591A\u6B21\uFF09
208
216
  --help, -h \u663E\u793A\u5E2E\u52A9
@@ -419,7 +427,222 @@ ${stderr.slice(0, MAX_READ_CHARS)}`);
419
427
  }
420
428
  }
421
429
  };
422
- var BUILTIN_TOOLS = [readTool, writeTool, editTool, bashTool];
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];
423
646
  function selectTools(options) {
424
647
  if (options.noTools) return [];
425
648
  let selected = [...BUILTIN_TOOLS];
@@ -452,6 +675,10 @@ import {
452
675
  createApprovalManager,
453
676
  FileApprovalStore
454
677
  } from "@aipack-ai/agent";
678
+ import {
679
+ createCompressionTransformer,
680
+ loadCompressionConfig
681
+ } from "@aipack-ai/compression";
455
682
  async function loadConfig(cwd) {
456
683
  for (const file of ["aipack.config.js", "aipack.config.mjs"]) {
457
684
  const full = path3.join(cwd, file);
@@ -528,6 +755,40 @@ async function resolveSessionKey(args, storage) {
528
755
  function sanitizeKey(name) {
529
756
  return name.replace(/[^a-zA-Z0-9_\-:.]/g, "_");
530
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
+ }
531
792
  var DEFAULT_APPROVAL_CAPABILITIES = ["fs:write", "shell:exec"];
532
793
  async function buildRuntime(options) {
533
794
  const { args, cwd } = options;
@@ -564,6 +825,13 @@ async function buildRuntime(options) {
564
825
  confirmFn: options.confirmFn
565
826
  });
566
827
  const systemPrompt = buildSystemPrompt(args);
828
+ const compressionTransformer = await buildCompressionTransformer({
829
+ args,
830
+ config,
831
+ model,
832
+ streamFn,
833
+ storage
834
+ });
567
835
  const runtime = await createRuntime({
568
836
  model: adaptAiModel(model.aiModel),
569
837
  streamFn,
@@ -576,7 +844,9 @@ async function buildRuntime(options) {
576
844
  permissionPolicy: policy,
577
845
  approvals: approvalManager,
578
846
  maxTurns: 50,
579
- compaction: { enabled: true }
847
+ transformers: compressionTransformer ? [compressionTransformer] : [],
848
+ // --no-compaction 时一并关闭内置摘要压缩(仅保留硬截断兜底)
849
+ compaction: args.noCompaction ? { enabled: false } : { enabled: true }
580
850
  });
581
851
  return {
582
852
  runtime,
@@ -584,7 +854,8 @@ async function buildRuntime(options) {
584
854
  storage,
585
855
  approvalManager,
586
856
  model,
587
- config
857
+ config,
858
+ compressionTransformer
588
859
  };
589
860
  }
590
861
  function buildPermissionPolicy(opts) {
@@ -717,9 +988,11 @@ var ChunkRenderer = class {
717
988
  async function runPrintMode(runtime, request) {
718
989
  const renderer = new ChunkRenderer({ toolStream: process.stderr });
719
990
  let error;
991
+ let usage;
720
992
  try {
721
993
  for await (const chunk of runtime.stream(request)) {
722
994
  if (chunk.type === "error") error = chunk.content;
995
+ if (chunk.type === "done" && chunk.result?.usage) usage = chunk.result.usage;
723
996
  renderer.render(chunk);
724
997
  }
725
998
  } catch (err) {
@@ -728,6 +1001,10 @@ async function runPrintMode(runtime, request) {
728
1001
  process.exitCode = 1;
729
1002
  return;
730
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
+ }
731
1008
  if (error) process.exitCode = 1;
732
1009
  }
733
1010
 
@@ -743,6 +1020,10 @@ async function runJsonMode(runtime, request) {
743
1020
  toolName: chunk.toolName,
744
1021
  toolCallId: chunk.toolCallId,
745
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,
746
1027
  timestamp: Date.now()
747
1028
  });
748
1029
  process.stdout.write(`${line}
@@ -842,6 +1123,7 @@ async function runInteractiveMode(opts) {
842
1123
  rl.on("line", onLine);
843
1124
  rl.prompt();
844
1125
  }
1126
+ let usageTotal = { input: 0, output: 0 };
845
1127
  async function send(text) {
846
1128
  if (!text.trim()) return;
847
1129
  busy = true;
@@ -857,6 +1139,14 @@ async function runInteractiveMode(opts) {
857
1139
  try {
858
1140
  for await (const chunk of runtime.stream(request)) {
859
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`));
860
1150
  }
861
1151
  } catch (err) {
862
1152
  console.log(chalk3.red(`\u9519\u8BEF: ${err instanceof Error ? err.message : String(err)}`));
@@ -937,10 +1227,22 @@ async function runInteractiveMode(opts) {
937
1227
  }
938
1228
  case "/clear":
939
1229
  runtime.clearSession(activeKey);
1230
+ usageTotal = { input: 0, output: 0 };
940
1231
  console.log(chalk3.green("\u4F1A\u8BDD\u5DF2\u6E05\u7A7A\uFF08\u4EC5\u5185\u5B58\uFF09"));
941
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
+ }
1241
+ break;
1242
+ }
942
1243
  case "/tools":
943
- console.log(chalk3.dim("\u5185\u7F6E\u5DE5\u5177\u901A\u8FC7 --tools/--exclude-tools \u914D\u7F6E\uFF1B\u5F53\u524D\u8FD0\u884C\u65F6\u672A\u63D0\u4F9B\u5217\u4E3E\u63A5\u53E3"));
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"));
944
1246
  break;
945
1247
  case "/approvals": {
946
1248
  if (!approvalManager) {
@@ -983,6 +1285,7 @@ async function runInteractiveMode(opts) {
983
1285
  /session \u5F53\u524D\u4F1A\u8BDD\u4FE1\u606F
984
1286
  /sessions \u5217\u51FA\u5386\u53F2\u4F1A\u8BDD
985
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
986
1289
  /approvals \u672A\u51B3\u5BA1\u6279\u5355
987
1290
  /approve <id> \u6279\u51C6
988
1291
  /deny <id> \u9A73\u56DE
@@ -1389,4 +1692,4 @@ export {
1389
1692
  createToolConfirmHandler,
1390
1693
  main
1391
1694
  };
1392
- //# sourceMappingURL=chunk-LXRCYMRS.js.map
1695
+ //# sourceMappingURL=chunk-TPMRQPLX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/version.ts","../package.json","../src/args.ts","../src/tools.ts","../src/builder.ts","../src/initial-message.ts","../src/modes/print.ts","../src/modes/render.ts","../src/modes/json.ts","../src/modes/interactive.ts","../src/prompt.ts","../src/select.ts","../src/confirm.ts","../src/cli.ts","../src/commands/approvals.ts","../src/commands/models.ts"],"sourcesContent":["/**\n * CLI 元信息与目录约定\n */\nimport os from 'node:os';\nimport path from 'node:path';\nimport pkg from '../package.json';\n\n/** 命令名:优先取 bin 名称(aipack),兜底包名去 scope */\nexport const APP_NAME =\n Object.keys(pkg.bin ?? {})[0] ?? pkg.name.replace(/^@[^/]+\\//, '');\nexport const VERSION = pkg.version;\n\n/** 全局配置目录(默认 ~/.aipack,可用 AIPACK_CONFIG_DIR 覆盖) */\nexport function defaultConfigDir(): string {\n return process.env.AIPACK_CONFIG_DIR ?? path.join(os.homedir(), '.aipack');\n}\n\n/**\n * CLI 会话存储目录(按工作目录分组):\n * ~/.aipack/cli-sessions/<cwd 安全编码>/<sessionKey>.json\n */\nexport function defaultSessionDir(cwd: string): string {\n return path.join(defaultConfigDir(), 'cli-sessions', encodeDir(cwd));\n}\n\n/** 将路径编码为安全目录名 */\nexport function encodeDir(p: string): string {\n return p.replace(/[^a-zA-Z0-9_-]/g, '_');\n}\n","{\n \"name\": \"@aipack-ai/cli\",\n \"version\": \"1.0.0\",\n \"description\": \"aipack CLI - 基于 @aipack-ai/agent 的终端 AI 助手\",\n \"type\": \"module\",\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"bin\": {\n \"aipack\": \"dist/bin.js\"\n },\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\"\n },\n \"./package.json\": \"./package.json\"\n },\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"prebuild\": \"[ -f ../agent/dist/index.d.ts ] || pnpm --filter @aipack-ai/agent build\",\n \"typecheck\": \"tsc --noEmit\",\n \"test\": \"node --import tsx --test test/*.test.ts\",\n \"dev\": \"tsx src/bin.ts\"\n },\n \"keywords\": [\n \"cli\",\n \"ai\",\n \"agent\",\n \"llm\",\n \"aipack\"\n ],\n \"license\": \"MIT\",\n \"engines\": {\n \"node\": \">=18.19.0\"\n },\n \"dependencies\": {\n \"@aipack-ai/agent\": \"workspace:*\",\n \"@aipack-ai/compression\": \"workspace:*\",\n \"chalk\": \"^5.3.0\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.12.0\",\n \"tsup\": \"^8.5.1\",\n \"tsx\": \"^4.16.0\",\n \"typescript\": \"^5.5.0\"\n }\n}\n","/**\n * CLI 参数解析与帮助文本(参考 pi 的 args.ts,适配 aipack)\n */\nimport type { ThinkingLevel } from '@aipack-ai/agent';\nimport { APP_NAME, VERSION } from './version.js';\n\nexport type Mode = 'text' | 'json';\n\nexport interface Args {\n provider?: string;\n model?: string;\n apiKey?: string;\n systemPrompt?: string;\n appendSystemPrompt?: string[];\n thinking?: ThinkingLevel;\n continue?: boolean;\n resume?: boolean;\n help?: boolean;\n version?: boolean;\n mode?: Mode;\n name?: string;\n noSession?: boolean;\n session?: string;\n sessionDir?: string;\n tools?: string[];\n excludeTools?: string[];\n noTools?: boolean;\n print?: boolean;\n listModels?: string | true;\n /** 保守模式:写文件与 shell 全部人工确认 */\n safe?: boolean;\n /** 关闭上下文压缩(内置摘要压缩与五级压缩 transformer 均不启用) */\n noCompaction?: boolean;\n /** 压缩配置文件路径(JSON,DeepPartial<CompressionConfig> 结构,叠加在默认配置上) */\n compactionConfig?: string;\n /** 位置参数(用户消息) */\n messages: string[];\n /** @file 引用 */\n fileArgs: string[];\n diagnostics: Array<{ type: 'warning' | 'error'; message: string }>;\n}\n\nconst VALID_THINKING_LEVELS = ['off', 'minimal', 'low', 'medium', 'high', 'max'] as const;\n\nexport function isValidThinkingLevel(level: string): level is ThinkingLevel {\n return (VALID_THINKING_LEVELS as readonly string[]).includes(level);\n}\n\nexport function parseArgs(args: string[]): Args {\n const result: Args = {\n messages: [],\n fileArgs: [],\n diagnostics: [],\n };\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n\n if (arg === '--help' || arg === '-h') {\n result.help = true;\n } else if (arg === '--version' || arg === '-v') {\n result.version = true;\n } else if (arg === '--mode' && i + 1 < args.length) {\n const mode = args[++i];\n if (mode === 'text' || mode === 'json') {\n result.mode = mode;\n } else {\n result.diagnostics.push({ type: 'error', message: `无效的 mode: ${mode}(可选 text / json)` });\n }\n } else if (arg === '--continue' || arg === '-c') {\n result.continue = true;\n } else if (arg === '--resume' || arg === '-r') {\n result.resume = true;\n } else if (arg === '--provider' && i + 1 < args.length) {\n result.provider = args[++i];\n } else if (arg === '--model' && i + 1 < args.length) {\n result.model = args[++i];\n } else if (arg === '--api-key' && i + 1 < args.length) {\n result.apiKey = args[++i];\n } else if (arg === '--system-prompt' && i + 1 < args.length) {\n result.systemPrompt = args[++i];\n } else if (arg === '--append-system-prompt' && i + 1 < args.length) {\n result.appendSystemPrompt = result.appendSystemPrompt ?? [];\n result.appendSystemPrompt.push(args[++i]);\n } else if (arg === '--thinking' && i + 1 < args.length) {\n const level = args[++i];\n if (isValidThinkingLevel(level)) {\n result.thinking = level;\n } else {\n result.diagnostics.push({\n type: 'warning',\n message: `无效的思考级别 \"${level}\"。可选: ${VALID_THINKING_LEVELS.join(', ')}`,\n });\n }\n } else if (arg === '--name' || arg === '-n') {\n if (i + 1 < args.length) {\n result.name = args[++i];\n } else {\n result.diagnostics.push({ type: 'error', message: '--name 需要一个值' });\n }\n } else if (arg === '--no-session') {\n result.noSession = true;\n } else if (arg === '--session' && i + 1 < args.length) {\n result.session = args[++i];\n } else if (arg === '--session-dir' && i + 1 < args.length) {\n result.sessionDir = args[++i];\n } else if ((arg === '--tools' || arg === '-t') && i + 1 < args.length) {\n result.tools = args[++i].split(',').map(s => s.trim()).filter(Boolean);\n } else if ((arg === '--exclude-tools' || arg === '-xt') && i + 1 < args.length) {\n result.excludeTools = args[++i].split(',').map(s => s.trim()).filter(Boolean);\n } else if (arg === '--no-tools' || arg === '-nt') {\n result.noTools = true;\n } else if (arg === '--safe') {\n result.safe = true;\n } else if (arg === '--no-compaction') {\n result.noCompaction = true;\n } else if (arg === '--compaction-config' && i + 1 < args.length) {\n result.compactionConfig = args[++i];\n } else if (arg === '--print' || arg === '-p') {\n result.print = true;\n const next = args[i + 1];\n if (next !== undefined && !next.startsWith('@') && !next.startsWith('-')) {\n result.messages.push(next);\n i++;\n }\n } else if (arg === '--list-models') {\n const next = args[i + 1];\n if (next !== undefined && !next.startsWith('-') && !next.startsWith('@')) {\n result.listModels = next;\n i++;\n } else {\n result.listModels = true;\n }\n } else if (arg.startsWith('@')) {\n result.fileArgs.push(arg.slice(1));\n } else if (arg.startsWith('--')) {\n result.diagnostics.push({ type: 'error', message: `未知选项: ${arg}` });\n } else if (arg.startsWith('-') && arg !== '-') {\n result.diagnostics.push({ type: 'error', message: `未知选项: ${arg}` });\n } else {\n result.messages.push(arg);\n }\n }\n\n return result;\n}\n\nexport function printHelp(): void {\n console.log(`${APP_NAME} ${VERSION} - 基于 @aipack-ai/agent 的终端 AI 助手\n\n${'用法:'}\n ${APP_NAME} [选项] [@文件...] [消息...]\n\n${'子命令:'}\n ${APP_NAME} approvals list 列出未决审批单\n ${APP_NAME} approvals approve <id> 批准审批单\n ${APP_NAME} approvals deny <id> 驳回审批单\n ${APP_NAME} --list-models [搜索] 列出可用模型\n\n${'模式:'}\n (默认) 交互模式(REPL)\n --print, -p [消息] 非交互:处理一次提示后退出(支持管道 stdin)\n --mode json 以 JSON 行输出全部流式事件\n\n${'模型选项:'}\n --provider <名称> 提供商(openai/deepseek/anthropic/google...)\n --model <id> 模型 ID,支持 provider/id 组合写法\n --api-key <key> API Key(覆盖环境变量)\n --thinking <级别> 思考级别: off/minimal/low/medium/high/max\n\n${'会话选项:'}\n --continue, -c 继续当前目录最近的会话\n --resume, -r 浏览并选择历史会话\n --session <名称> 使用指定会话\n --name, -n <名称> 为新会话命名\n --session-dir <目录> 自定义会话存储目录\n --no-session 临时会话(不持久化)\n\n${'工具选项:'}\n --tools, -t <列表> 工具白名单(逗号分隔)\n --exclude-tools, -xt <列表> 工具黑名单(逗号分隔)\n --no-tools, -nt 禁用全部工具\n --safe 保守模式:写文件/shell 全部人工确认\n\n 内置工具: read, write, edit, bash, find, grep, ls\n 默认权限: 读写文件静默放行(工作区范围内);bash 仅危险命令\n (sudo、rm -rf ~、磁盘写入、远程脚本管道等)需确认\n\n${'其他:'}\n --no-compaction 关闭上下文压缩(长会话可能溢出)\n --compaction-config <文件> 压缩配置 JSON(覆盖默认阈值)\n --system-prompt <文本> 替换默认系统提示词\n --append-system-prompt <文本> 追加系统提示词(可多次)\n --help, -h 显示帮助\n --version, -v 显示版本\n\n${'示例:'}\n # 交互模式\n ${APP_NAME}\n\n # 非交互单次提问(支持管道)\n cat README.md | ${APP_NAME} -p \"总结这段文本\"\n\n # 指定模型\n ${APP_NAME} --provider deepseek --model deepseek-chat \"你好\"\n\n # provider/id 组合写法\n ${APP_NAME} --model anthropic/claude-sonnet-4-20250514 \"帮我重构代码\"\n\n # 附带文件上下文\n ${APP_NAME} @package.json \"分析这个文件的依赖\"\n\n # 继续上次会话\n ${APP_NAME} -c \"我们刚才聊到哪里了?\"\n\n # 只读模式\n ${APP_NAME} --tools read -p \"审查 src/ 下的代码\"\n\n${'环境变量:'}\n OPENAI_API_KEY / DEEPSEEK_API_KEY / ANTHROPIC_API_KEY / GOOGLE_API_KEY ...\n AIPACK_CONFIG_DIR 配置目录(默认 ~/.aipack)\n`);\n}\n","/**\n * 内置工具:read / write / edit / bash\n *\n * 参考 pi 的 coding-agent 默认工具集。每个工具声明 permissions 能力,\n * 供框架级 PermissionPolicy 裁决(如 fs:write → confirm / pending)。\n */\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { spawn } from 'node:child_process';\nimport type { Tool, ToolResult } from '@aipack-ai/agent';\n\n/** 工作区根目录:文件路径解析的基准(防止越界访问任意路径) */\nexport const workspaceRoot = process.cwd();\n\nfunction resolveInWorkspace(p: string): string {\n const abs = path.resolve(workspaceRoot, p);\n if (!abs.startsWith(workspaceRoot)) {\n throw new Error(`路径越界:${p}(工作区:${workspaceRoot})`);\n }\n return abs;\n}\n\nfunction textResult(text: string, details?: unknown): ToolResult {\n return { content: [{ type: 'text', text }], details: details ?? {} };\n}\n\nfunction errorResult(message: string): ToolResult {\n return {\n content: [{ type: 'text', text: `错误: ${message}` }],\n details: { error: message },\n };\n}\n\n/** 单文件读取上限(字符),超出截断 */\nconst MAX_READ_CHARS = 100_000;\n\n// ─── read ─────────────────────────────────────────────────────────\n\nexport const readTool: Tool = {\n name: 'read',\n description: '读取文件内容。返回文本内容,超长自动截断。',\n parameters: {\n type: 'object',\n properties: {\n file: { type: 'string', description: '文件路径(相对工作区)' },\n offset: { type: 'number', description: '起始行号(从 1 开始,可选)' },\n limit: { type: 'number', description: '读取行数(可选)' },\n },\n required: ['file'],\n },\n permissions: ['fs:read'],\n async execute(_id, rawArgs) {\n const args = rawArgs as { file: string; offset?: number; limit?: number };\n try {\n const abs = resolveInWorkspace(args.file);\n let content = await fs.readFile(abs, 'utf8');\n if (args.offset !== undefined || args.limit !== undefined) {\n const lines = content.split('\\n');\n const start = Math.max(0, (args.offset ?? 1) - 1);\n const end = args.limit !== undefined ? start + args.limit : lines.length;\n content = lines.slice(start, end).join('\\n');\n }\n if (content.length > MAX_READ_CHARS) {\n content = content.slice(0, MAX_READ_CHARS) + `\\n...[截断,共 ${content.length} 字符]`;\n }\n return textResult(content, { file: args.file, truncated: content.length >= MAX_READ_CHARS });\n } catch (err) {\n return errorResult(String(err instanceof Error ? err.message : err));\n }\n },\n};\n\n// ─── write ────────────────────────────────────────────────────────\n\nexport const writeTool: Tool = {\n name: 'write',\n description: '写入文件(创建或覆盖)。自动创建父目录。',\n parameters: {\n type: 'object',\n properties: {\n file: { type: 'string', description: '文件路径(相对工作区)' },\n content: { type: 'string', description: '完整文件内容' },\n },\n required: ['file', 'content'],\n },\n permissions: ['fs:write'],\n async execute(_id, rawArgs) {\n const args = rawArgs as { file: string; content: string };\n try {\n const abs = resolveInWorkspace(args.file);\n await fs.mkdir(path.dirname(abs), { recursive: true });\n await fs.writeFile(abs, args.content, 'utf8');\n return textResult(`已写入 ${args.file}(${args.content.length} 字符)`, { file: args.file });\n } catch (err) {\n return errorResult(String(err instanceof Error ? err.message : err));\n }\n },\n};\n\n// ─── edit ─────────────────────────────────────────────────────────\n\nexport const editTool: Tool = {\n name: 'edit',\n description: '编辑文件:将 oldString 的首次出现替换为 newString。oldString 必须唯一匹配。',\n parameters: {\n type: 'object',\n properties: {\n file: { type: 'string', description: '文件路径(相对工作区)' },\n oldString: { type: 'string', description: '被替换的文本(须在文件中唯一)' },\n newString: { type: 'string', description: '替换后的文本' },\n },\n required: ['file', 'oldString', 'newString'],\n },\n permissions: ['fs:write'],\n async execute(_id, rawArgs) {\n const args = rawArgs as { file: string; oldString: string; newString: string };\n try {\n const abs = resolveInWorkspace(args.file);\n const content = await fs.readFile(abs, 'utf8');\n const first = content.indexOf(args.oldString);\n if (first === -1) {\n return errorResult(`在 ${args.file} 中未找到 oldString`);\n }\n if (content.indexOf(args.oldString, first + 1) !== -1) {\n return errorResult(`oldString 在 ${args.file} 中出现多次,请提供更长的上下文使其唯一`);\n }\n const updated = content.slice(0, first) + args.newString + content.slice(first + args.oldString.length);\n await fs.writeFile(abs, updated, 'utf8');\n return textResult(`已编辑 ${args.file}`, { file: args.file });\n } catch (err) {\n return errorResult(String(err instanceof Error ? err.message : err));\n }\n },\n};\n\n// ─── bash ─────────────────────────────────────────────────────────\n\nfunction runShell(command: string, timeoutMs: number): Promise<{ stdout: string; stderr: string; code: number }> {\n return new Promise(resolve => {\n const child = spawn(command, {\n shell: process.env.SHELL ?? '/bin/bash',\n cwd: workspaceRoot,\n env: { ...process.env, AIPACK_CLI: 'true' },\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n let stdout = '';\n let stderr = '';\n let settled = false;\n\n const timer = setTimeout(() => {\n if (!settled) {\n settled = true;\n child.kill('SIGKILL');\n resolve({ stdout, stderr: stderr + `\\n[命令超时(${timeoutMs}ms)被终止]`, code: 124 });\n }\n }, timeoutMs);\n\n child.stdout.on('data', d => { stdout += d.toString(); });\n child.stderr.on('data', d => { stderr += d.toString(); });\n child.on('close', code => {\n if (!settled) {\n settled = true;\n clearTimeout(timer);\n resolve({ stdout, stderr, code: code ?? 0 });\n }\n });\n child.on('error', err => {\n if (!settled) {\n settled = true;\n clearTimeout(timer);\n resolve({ stdout, stderr: String(err), code: -1 });\n }\n });\n });\n}\n\nexport const bashTool: Tool = {\n name: 'bash',\n description: '在工作区执行 shell 块命令并返回输出。适用于文件搜索、构建、测试等操作。',\n parameters: {\n type: 'object',\n properties: {\n command: { type: 'string', description: '要执行的命令' },\n timeoutMs: { type: 'number', description: '超时毫秒数(默认 60000)' },\n },\n required: ['command'],\n },\n permissions: ['shell:exec'],\n async execute(_id, rawArgs) {\n const args = rawArgs as { command: string; timeoutMs?: number };\n const timeout = args.timeoutMs ?? 60_000;\n try {\n const { stdout, stderr, code } = await runShell(args.command, timeout);\n const parts: string[] = [];\n if (stdout.trim()) parts.push(`[stdout]\\n${stdout.slice(0, MAX_READ_CHARS)}`);\n if (stderr.trim()) parts.push(`[stderr]\\n${stderr.slice(0, MAX_READ_CHARS)}`);\n parts.push(`[退出码 ${code}]`);\n return textResult(parts.join('\\n'), { command: args.command, code });\n } catch (err) {\n return errorResult(String(err instanceof Error ? err.message : err));\n }\n },\n};\n\n// ─── 文件检索辅助 ─────────────────────────────────────────────────\n\n/** 遍历时剪枝的目录(依赖产物与版本控制元数据) */\nconst PRUNED_DIRS = new Set(['node_modules', '.git', 'dist', '.next', '.turbo', 'coverage']);\n\n/** 单文件读取上限(grep 用,跳过超大文件) */\nconst MAX_GREP_FILE_BYTES = 2 * 1024 * 1024;\n\n/** glob → RegExp:支持 **(跨目录)、*(单段)、?(单字符) */\nfunction globToRegExp(pattern: string): RegExp {\n let re = '';\n for (let i = 0; i < pattern.length; i++) {\n const c = pattern[i];\n if (c === '*') {\n if (pattern[i + 1] === '*') {\n re += '.*';\n i++;\n if (pattern[i + 1] === '/') i++; // \"**/\" 吞掉分隔符\n } else {\n re += '[^/]*';\n }\n } else if (c === '?') {\n re += '[^/]';\n } else {\n re += c.replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&');\n }\n }\n return new RegExp(`^${re}$`);\n}\n\n/** 递归遍历目录,返回相对搜索根的 posix 路径(剪枝 PRUNED_DIRS) */\nasync function walkFiles(root: string, maxEntries: number): Promise<string[]> {\n const out: string[] = [];\n const queue: string[] = [''];\n while (queue.length > 0 && out.length < maxEntries) {\n const rel = queue.shift()!;\n const abs = path.join(root, rel);\n let entries;\n try {\n entries = await fs.readdir(abs, { withFileTypes: true });\n } catch {\n continue; // 无权限等 → 跳过\n }\n for (const e of entries) {\n if (out.length >= maxEntries) break;\n const childRel = rel ? `${rel}/${e.name}` : e.name;\n if (e.isDirectory()) {\n if (!PRUNED_DIRS.has(e.name)) queue.push(childRel);\n } else if (e.isFile()) {\n out.push(childRel);\n }\n }\n }\n return out;\n}\n\n// ─── find ─────────────────────────────────────────────────────────\n\nexport const findTool: Tool = {\n name: 'find',\n description: '按 glob 模式查找文件。支持 ** 跨目录匹配。示例: \"**/*.ts\"、\"src/**/*.spec.ts\"',\n parameters: {\n type: 'object',\n properties: {\n pattern: { type: 'string', description: 'glob 模式,如 \"*.md\" 或 \"**/*.ts\"' },\n path: { type: 'string', description: '搜索目录(相对工作区,默认 .)' },\n limit: { type: 'number', description: '最大结果数(默认 1000)' },\n },\n required: ['pattern'],\n },\n permissions: ['fs:read'],\n async execute(_id, rawArgs) {\n const args = rawArgs as { pattern: string; path?: string; limit?: number };\n const limit = args.limit ?? 1000;\n try {\n const root = resolveInWorkspace(args.path ?? '.');\n const re = globToRegExp(args.pattern);\n // 遍历上限与结果上限解耦:遍历足够多文件后再过滤,避免低匹配率时提前截断\n const files = await walkFiles(root, Math.max(limit * 10, 10_000));\n const matches = files.filter(f => re.test(f));\n const limited = matches.slice(0, limit);\n if (limited.length === 0) {\n return textResult(`未找到匹配 \"${args.pattern}\" 的文件`, { pattern: args.pattern });\n }\n const suffix = matches.length > limited.length ? `\\n...[共 ${matches.length} 个,已截断至 ${limit}]` : '';\n return textResult(`${limited.join('\\n')}${suffix}`, {\n pattern: args.pattern,\n count: matches.length,\n truncated: matches.length > limited.length,\n });\n } catch (err) {\n return errorResult(String(err instanceof Error ? err.message : err));\n }\n },\n};\n\n// ─── grep ─────────────────────────────────────────────────────────\n\nexport const grepTool: Tool = {\n name: 'grep',\n description: '在文件内容中搜索模式(默认正则)。自动跳过二进制/超大文件与 node_modules。输出 file:line: text',\n parameters: {\n type: 'object',\n properties: {\n pattern: { type: 'string', description: '搜索模式(正则,或配合 literal 使用字面量)' },\n path: { type: 'string', description: '搜索的目录或文件(相对工作区,默认 .)' },\n glob: { type: 'string', description: '文件名过滤 glob,如 \"*.ts\"' },\n ignoreCase: { type: 'boolean', description: '忽略大小写(默认 false)' },\n literal: { type: 'boolean', description: '按字面量而非正则解释 pattern(默认 false)' },\n context: { type: 'number', description: '每个匹配前后显示的行数(默认 0)' },\n limit: { type: 'number', description: '最大匹配数(默认 100)' },\n },\n required: ['pattern'],\n },\n permissions: ['fs:read'],\n async execute(_id, rawArgs) {\n const args = rawArgs as {\n pattern: string; path?: string; glob?: string;\n ignoreCase?: boolean; literal?: boolean; context?: number; limit?: number;\n };\n const limit = args.limit ?? 100;\n const context = args.context ?? 0;\n try {\n const target = resolveInWorkspace(args.path ?? '.');\n const re = new RegExp(\n args.literal ? args.pattern.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&') : args.pattern,\n args.ignoreCase ? 'i' : '',\n );\n const globRe = args.glob ? globToRegExp(args.glob) : undefined;\n\n // 确定待搜文件清单(相对工作区)\n let files: Array<{ rel: string; abs: string }>;\n const stat = await fs.stat(target);\n if (stat.isFile()) {\n files = [{ rel: path.relative(workspaceRoot, target), abs: target }];\n } else if (stat.isDirectory()) {\n files = (await walkFiles(target, 20_000))\n .filter(f => !globRe || globRe.test(f) || globRe.test(f.split('/').pop()!))\n .map(f => ({ rel: f, abs: path.join(target, f) }));\n } else {\n return errorResult(`不是文件或目录: ${args.path}`);\n }\n\n const out: string[] = [];\n let matchCount = 0;\n let truncated = false;\n\n for (const file of files) {\n if (matchCount >= limit) { truncated = true; break; }\n let buf: Buffer;\n try {\n const st = await fs.stat(file.abs);\n if (st.size > MAX_GREP_FILE_BYTES) continue;\n buf = await fs.readFile(file.abs);\n } catch {\n continue;\n }\n if (buf.includes(0)) continue; // 二进制文件\n const lines = buf.toString('utf8').split('\\n');\n\n // 收集本文件匹配行号\n const hitLines: number[] = [];\n for (let i = 0; i < lines.length && matchCount + hitLines.length < limit; i++) {\n if (re.test(lines[i])) hitLines.push(i);\n }\n if (hitLines.length === 0) continue;\n matchCount += hitLines.length;\n\n // 带去重的行号区间(context 展开)\n const show = new Set<number>();\n for (const h of hitLines) {\n for (let i = Math.max(0, h - context); i <= Math.min(lines.length - 1, h + context); i++) {\n show.add(i);\n }\n }\n for (const i of [...show].sort((a, b) => a - b)) {\n const marker = hitLines.includes(i) ? '>' : ' ';\n out.push(`${file.rel}:${i + 1}:${marker} ${lines[i].slice(0, 500)}`);\n }\n }\n\n if (out.length === 0) {\n return textResult(`未找到匹配 \"${args.pattern}\" 的内容`, { pattern: args.pattern, count: 0 });\n }\n const suffix = truncated ? `\\n...[已达 ${limit} 个匹配上限,截断]` : '';\n return textResult(`${out.join('\\n')}${suffix}`, {\n pattern: args.pattern,\n count: matchCount,\n truncated,\n });\n } catch (err) {\n return errorResult(String(err instanceof Error ? err.message : err));\n }\n },\n};\n\n// ─── ls ───────────────────────────────────────────────────────────\n\nexport const lsTool: Tool = {\n name: 'ls',\n description: '列出目录内容(目录带 / 后缀,目录在前)。探索项目结构时优先使用。',\n parameters: {\n type: 'object',\n properties: {\n path: { type: 'string', description: '目录路径(相对工作区,默认 .)' },\n limit: { type: 'number', description: '最大条目数(默认 500)' },\n },\n },\n permissions: ['fs:read'],\n async execute(_id, rawArgs) {\n const args = rawArgs as { path?: string; limit?: number };\n const limit = args.limit ?? 500;\n try {\n const abs = resolveInWorkspace(args.path ?? '.');\n const stat = await fs.stat(abs);\n if (!stat.isDirectory()) {\n return textResult(path.relative(workspaceRoot, abs) || abs);\n }\n const entries = await fs.readdir(abs, { withFileTypes: true });\n const sorted = entries\n .filter(e => e.isDirectory() || e.isFile() || e.isSymbolicLink())\n .sort((a, b) => {\n const ad = a.isDirectory() ? 0 : 1;\n const bd = b.isDirectory() ? 0 : 1;\n return ad !== bd ? ad - bd : a.name.localeCompare(b.name);\n });\n const limited = sorted.slice(0, limit);\n if (limited.length === 0) {\n return textResult('(空目录)', {});\n }\n const lines = limited.map(e =>\n e.isDirectory() ? `${e.name}/` : e.isSymbolicLink() ? `${e.name}@` : e.name,\n );\n const suffix = sorted.length > limited.length ? `\\n...[共 ${sorted.length} 项,已截断至 ${limit}]` : '';\n return textResult(`${lines.join('\\n')}${suffix}`, {\n path: args.path ?? '.',\n count: sorted.length,\n truncated: sorted.length > limited.length,\n });\n } catch (err) {\n return errorResult(String(err instanceof Error ? err.message : err));\n }\n },\n};\n\n// ─── 工具集组装 ───────────────────────────────────────────────────\n\nexport const BUILTIN_TOOLS: Tool[] = [readTool, writeTool, editTool, bashTool, findTool, grepTool, lsTool];\n\n/**\n * 按白名单/黑名单过滤内置工具。\n * - tools: 仅保留白名单中的工具\n * - excludeTools: 移除黑名单中的工具\n * - noTools: 返回空数组\n */\nexport function selectTools(options: {\n tools?: string[];\n excludeTools?: string[];\n noTools?: boolean;\n}): Tool[] {\n if (options.noTools) return [];\n let selected = [...BUILTIN_TOOLS];\n if (options.tools && options.tools.length > 0) {\n const allow = new Set(options.tools);\n selected = selected.filter(t => allow.has(t.name));\n }\n if (options.excludeTools && options.excludeTools.length > 0) {\n const deny = new Set(options.excludeTools);\n selected = selected.filter(t => !deny.has(t.name));\n }\n return selected;\n}\n","/**\n * Runtime 构建器:把 CLI 参数解析结果组装成可运行的 Runtime。\n *\n * 职责:\n * 1. 加载 aipack.config.js(可选:approvals.enabled 等)\n * 2. 解析模型(--model 支持 provider/id;未配置时自动探测有 API Key 的提供商)\n * 3. 会话存储与 sessionKey 选择(--continue 找最新 / --session / --name / 自动生成)\n * 4. 权限策略(fs:read 放行;fs:write / shell:exec 按配置走 confirm 或 pending 审批)\n */\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport {\n createRuntime,\n adaptAiModel,\n createStreamFnFromAi,\n getBuiltinModel,\n getBuiltinModels,\n getBuiltinProviders,\n BUILTIN_PROVIDERS,\n hasProviderConfigured,\n createFileSessionStorage,\n createPermissionPolicy,\n createApprovalManager,\n FileApprovalStore,\n} from '@aipack-ai/agent';\nimport {\n createCompressionTransformer,\n loadCompressionConfig,\n type CompressionConfig,\n type ContextCompressionTransformer,\n} from '@aipack-ai/compression';\nimport type {\n Runtime,\n Tool,\n SessionStorage,\n ApprovalManager,\n PermissionRequest,\n AiModel,\n PermissionPolicy,\n} from '@aipack-ai/agent';\nimport type { Args } from './args.js';\nimport { selectTools } from './tools.js';\nimport { defaultSessionDir, defaultConfigDir, VERSION } from './version.js';\n\n// ─── 配置文件 ─────────────────────────────────────────────────────\n\nexport interface AipackCliConfig {\n approvals?: {\n /** 是否启用异步审批(pending 决策 + ApprovalManager)。默认 false(内联 confirm) */\n enabled?: boolean;\n /** 触发审批的能力列表(默认 fs:write 与 shell:exec) */\n capabilities?: string[];\n };\n /** 额外权限规则(追加在内置规则之前,优先裁决) */\n permissionRules?: Array<{\n toolName?: string;\n permission?: string;\n decision: 'allow' | 'deny' | 'confirm' | 'pending';\n }>;\n}\n\nexport async function loadConfig(cwd: string): Promise<AipackCliConfig> {\n for (const file of ['aipack.config.js', 'aipack.config.mjs']) {\n const full = path.join(cwd, file);\n try {\n await fs.access(full);\n const mod = await import(pathToFileURL(full).href);\n const config = (mod.default ?? mod) as AipackCliConfig;\n return config ?? {};\n } catch {\n // 文件不存在或加载失败 → 继续尝试 / 返回空配置\n }\n }\n return {};\n}\n\n// ─── 模型解析 ─────────────────────────────────────────────────────\n\nexport interface ResolvedModel {\n aiModel: AiModel;\n /** 是否为目录外自定义模型 */\n custom: boolean;\n}\n\n/** 从 --model \"provider/id\" 或 --provider + --model 解析 */\nfunction splitModelSpec(args: Args): { provider?: string; modelId?: string } {\n if (args.model && args.model.includes('/')) {\n const idx = args.model.indexOf('/');\n return { provider: args.model.slice(0, idx), modelId: args.model.slice(idx + 1) };\n }\n return { provider: args.provider, modelId: args.model };\n}\n\n/** 第一个已配置 API Key 的内置提供商 */\nfunction detectDefaultProvider(): { id: string; modelId: string } {\n for (const p of getBuiltinProviders()) {\n if (hasProviderConfigured(p.id)) {\n const models = getBuiltinModels(p.id);\n if (models.length > 0) return { id: p.id, modelId: models[0].id };\n }\n }\n return { id: 'openai', modelId: 'gpt-4o-mini' };\n}\n\n/** 为目录外模型构造最小可用的 ai Model(推断 API 类型与 baseUrl) */\nfunction buildCustomModel(providerId: string, modelId: string): AiModel {\n const meta = BUILTIN_PROVIDERS.find(p => p.id === providerId);\n const api = providerId === 'anthropic' ? 'anthropic-messages' : 'openai-completions';\n return {\n id: modelId,\n name: modelId,\n provider: providerId,\n api,\n baseUrl: meta?.baseUrl,\n reasoning: false,\n input: ['text'],\n contextWindow: 128000,\n maxTokens: 16384,\n } as AiModel;\n}\n\nexport function resolveModel(args: Args): ResolvedModel {\n const spec = splitModelSpec(args);\n const fallback = detectDefaultProvider();\n const providerId = spec.provider ?? fallback.id;\n const modelId = spec.modelId ?? fallback.modelId;\n\n const builtin = getBuiltinModel(providerId, modelId);\n if (builtin) return { aiModel: builtin, custom: false };\n return { aiModel: buildCustomModel(providerId, modelId), custom: true };\n}\n\n// ─── 会话解析 ─────────────────────────────────────────────────────\n\nexport interface SessionChoice {\n sessionKey: string;\n /** 是否复用了已存在的会话(--continue / --session) */\n resumed: boolean;\n}\n\n/** 列出存储中按 updatedAt 降序的会话 key(最多 50 个) */\nexport async function listSessionsByRecency(storage: SessionStorage): Promise<string[]> {\n const keys = await storage.list();\n const entries = await Promise.all(\n keys.slice(0, 200).map(async key => {\n const s = await storage.load(key);\n return { key, updatedAt: s?.updatedAt ?? '' };\n }),\n );\n return entries\n .sort((a, b) => b.updatedAt.localeCompare(a.updatedAt))\n .map(e => e.key);\n}\n\nexport async function resolveSessionKey(\n args: Args,\n storage: SessionStorage | undefined,\n): Promise<SessionChoice> {\n if (args.noSession) return { sessionKey: `ephemeral-${Date.now().toString(36)}`, resumed: false };\n if (args.session) return { sessionKey: sanitizeKey(args.session), resumed: true };\n if (args.name) return { sessionKey: sanitizeKey(args.name), resumed: false };\n\n if (args.continue && storage) {\n const recent = await listSessionsByRecency(storage);\n if (recent.length > 0) return { sessionKey: recent[0], resumed: true };\n // 没有历史会话 → 落到新建\n }\n\n return { sessionKey: `s-${Date.now().toString(36)}`, resumed: false };\n}\n\nfunction sanitizeKey(name: string): string {\n return name.replace(/[^a-zA-Z0-9_\\-:.]/g, '_');\n}\n\n// ─── 权限策略 ─────────────────────────────────────────────────────\n\nexport interface BuildRuntimeOptions {\n args: Args;\n cwd: string;\n /** 内联人工确认回调(confirm 决策时调用;返回 true 放行) */\n confirmFn?: (req: PermissionRequest) => Promise<boolean>;\n /** 覆盖审批是否启用(默认读配置文件) */\n approvalsEnabled?: boolean;\n}\n\nexport interface BuiltRuntime {\n runtime: Runtime;\n sessionKey: string;\n storage?: SessionStorage;\n approvalManager?: ApprovalManager;\n model: ResolvedModel;\n config: AipackCliConfig;\n /** 五级压缩转换器(--no-compaction 时为 undefined) */\n compressionTransformer?: ContextCompressionTransformer;\n}\n\n// ─── 上下文压缩 ───────────────────────────────────────────────────\n\n/**\n * 加载压缩配置:默认配置 + aipack.config.js 的 compression 字段 +\n * --compaction-config 指定的 JSON 文件(后者优先级最高)。\n * 文件读取/解析失败仅告警,回退默认配置(不阻塞启动)。\n */\nasync function loadCompressionSettings(\n args: Args,\n config: AipackCliConfig,\n): Promise<CompressionConfig> {\n const overrides: Record<string, unknown> = {};\n const fromConfigFile = (config as { compression?: Record<string, unknown> }).compression;\n if (fromConfigFile) Object.assign(overrides, fromConfigFile);\n\n if (args.compactionConfig) {\n try {\n const raw = await fs.readFile(args.compactionConfig, 'utf8');\n Object.assign(overrides, JSON.parse(raw));\n } catch (err) {\n console.warn(`[aipack] 压缩配置文件加载失败(${args.compactionConfig}),使用默认配置:`,\n err instanceof Error ? err.message : String(err));\n }\n }\n\n return loadCompressionConfig(overrides);\n}\n\n/**\n * 构建五级压缩转换器(L1 裁剪 → L2 摘要 → L3 状态提取 → L4 检查点 → L5 新会话交接)。\n * 作为第一级 transformer 加入 runtime 降级链:五级压缩 → runtime 内置摘要压缩 → 硬截断。\n */\nasync function buildCompressionTransformer(opts: {\n args: Args;\n config: AipackCliConfig;\n model: ResolvedModel;\n streamFn: ReturnType<typeof createStreamFnFromAi>;\n storage?: SessionStorage;\n}): Promise<ContextCompressionTransformer | undefined> {\n if (opts.args.noCompaction) return undefined;\n\n const compressionConfig = await loadCompressionSettings(opts.args, opts.config);\n const transformer = createCompressionTransformer({\n config: compressionConfig,\n model: adaptAiModel(opts.model.aiModel),\n streamFn: opts.streamFn,\n sessionStorage: opts.storage,\n contextWindow: opts.model.aiModel.contextWindow,\n });\n\n // L5 交接钩子:runtime 暂无 switchSession API,先输出提示(历史会话已归档保留)\n transformer.setHandoffHook(({ handoff }) => {\n console.warn(\n `[aipack] 上下文已达极限,已生成交接文档并切换到新会话 ${handoff.newSessionId}。` +\n `恢复: aipack --session ${handoff.newSessionId}`,\n );\n });\n\n return transformer;\n}\n\nconst DEFAULT_APPROVAL_CAPABILITIES = ['fs:write', 'shell:exec'];\n\nexport async function buildRuntime(options: BuildRuntimeOptions): Promise<BuiltRuntime> {\n const { args, cwd } = options;\n const config = await loadConfig(cwd);\n\n // ── 模型与 streamFn ──\n const model = resolveModel(args);\n const streamFn = createStreamFnFromAi(model.aiModel, {\n apiKey: args.apiKey,\n });\n\n // ── 工具 ──\n const tools: Tool[] = selectTools({\n tools: args.tools,\n excludeTools: args.excludeTools,\n noTools: args.noTools,\n });\n\n // ── 会话存储 ──\n const storage = args.noSession\n ? undefined\n : createFileSessionStorage({\n baseDir: args.sessionDir ?? defaultSessionDir(cwd),\n });\n const session = await resolveSessionKey(args, storage);\n\n // ── 审批与权限 ──\n const approvalsEnabled = options.approvalsEnabled ?? config.approvals?.enabled === true;\n const approvalCaps = new Set(config.approvals?.capabilities ?? DEFAULT_APPROVAL_CAPABILITIES);\n\n let approvalManager: ApprovalManager | undefined;\n if (approvalsEnabled) {\n approvalManager = createApprovalManager({\n store: new FileApprovalStore({\n baseDir: path.join(defaultConfigDir(), 'approvals'),\n }),\n });\n await approvalManager.restore();\n }\n\n const policy = buildPermissionPolicy({\n config,\n approvalCaps,\n approvalsEnabled,\n safe: args.safe === true,\n confirmFn: options.confirmFn,\n });\n\n // ── 系统提示词 ──\n const systemPrompt = buildSystemPrompt(args);\n\n // ── 上下文压缩(五级 transformer + runtime 内置摘要兜底)──\n const compressionTransformer = await buildCompressionTransformer({\n args,\n config,\n model,\n streamFn,\n storage,\n });\n\n // ── 组装 Runtime ──\n const runtime = await createRuntime({\n model: adaptAiModel(model.aiModel),\n streamFn,\n systemPrompt,\n tools,\n workspace: cwd,\n config: { cli: true, version: VERSION, cwd },\n sessionStorage: storage,\n thinkingLevel: args.thinking,\n permissionPolicy: policy,\n approvals: approvalManager,\n maxTurns: 50,\n transformers: compressionTransformer ? [compressionTransformer] : [],\n // --no-compaction 时一并关闭内置摘要压缩(仅保留硬截断兜底)\n compaction: args.noCompaction ? { enabled: false } : { enabled: true },\n });\n\n return {\n runtime,\n sessionKey: session.sessionKey,\n storage,\n approvalManager,\n model,\n config,\n compressionTransformer,\n };\n}\n\nfunction buildPermissionPolicy(opts: {\n config: AipackCliConfig;\n approvalCaps: Set<string>;\n approvalsEnabled: boolean;\n safe: boolean;\n confirmFn?: (req: PermissionRequest) => Promise<boolean>;\n}): PermissionPolicy {\n const { config, approvalCaps, approvalsEnabled, safe, confirmFn } = opts;\n\n const customRules = (config.permissionRules ?? []).map(r => ({\n name: `config:${r.permission ?? r.toolName ?? '*'}`,\n toolName: r.toolName ? new RegExp(`^${r.toolName}$`) : undefined,\n permission: r.permission,\n decision: r.decision,\n }));\n\n /**\n * 高风险能力默认决策(优先级:approvals > safe > 智能默认):\n * - approvals.enabled → pending(异步审批)\n * - --safe → confirm(全部人工确认)\n * - 默认 → fs:write 放行(工作区防护兜底)、shell:exec 走 confirm,\n * 由 confirmFn 自动放行非危险命令(危险命令才弹选择器)\n */\n const highRiskRules = [...approvalCaps].flatMap(cap => {\n let decision: 'pending' | 'confirm' | 'allow';\n if (approvalsEnabled) decision = 'pending';\n else if (safe) decision = 'confirm';\n else decision = cap === 'fs:write' ? 'allow' : 'confirm';\n return [{ name: `builtin:${cap}:${decision}`, permission: cap, decision }];\n });\n\n return createPermissionPolicy({\n rules: [\n ...customRules,\n ...highRiskRules,\n { name: 'builtin:read', permission: 'fs:read', decision: 'allow' as const },\n // 未声明 permissions 的安全工具放行\n { name: 'builtin:safe-tools', decision: 'allow' as const },\n ],\n confirmFn,\n defaultDecision: 'deny',\n });\n}\n\nfunction buildSystemPrompt(args: Args): string {\n const base = args.systemPrompt ?? [\n '你是 aipack,一个终端里的 AI 编程助手。',\n '你可以使用工具读写文件、执行命令来完成用户的任务。',\n '回答保持简洁、技术化,使用与用户相同的语言。',\n ].join('\\n');\n\n const appended = args.appendSystemPrompt ?? [];\n return [base, ...appended].join('\\n\\n');\n}\n","/**\n * 初始消息组装:位置参数消息 + @file 引用 + 管道 stdin\n */\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\n\n/** 判定文件是否为图片(走 Request.media 通道) */\nconst IMAGE_EXT = new Set(['.png', '.jpg', '.jpeg', '.gif', '.webp', '.bmp']);\n\nexport interface InitialMessage {\n /** 文本消息(拼接 @文本文件 与管道内容) */\n text: string;\n /** 图片附件(base64) */\n media: string[];\n}\n\nexport async function buildInitialMessage(\n messages: string[],\n fileArgs: string[],\n stdinText: string | undefined,\n): Promise<InitialMessage> {\n const parts: string[] = [];\n const media: string[] = [];\n\n for (const file of fileArgs) {\n const abs = path.resolve(process.cwd(), file);\n const ext = path.extname(abs).toLowerCase();\n try {\n if (IMAGE_EXT.has(ext)) {\n const buf = await fs.readFile(abs);\n media.push(`data:image/${ext.slice(1)};base64,${buf.toString('base64')}`);\n } else {\n const content = await fs.readFile(abs, 'utf8');\n parts.push(`--- 文件: ${file} ---\\n${content}\\n--- 结束 ---`);\n }\n } catch (err) {\n parts.push(`[文件 ${file} 读取失败: ${err instanceof Error ? err.message : err}]`);\n }\n }\n\n if (stdinText && stdinText.trim()) {\n parts.push(`--- stdin ---\\n${stdinText.trim()}\\n--- 结束 ---`);\n }\n\n if (messages.length > 0) {\n parts.unshift(messages.join('\\n'));\n }\n\n return { text: parts.join('\\n\\n'), media };\n}\n","/**\n * print 模式(-p):非交互,处理一次提示后退出。\n * 文本回复写 stdout(可管道),工具/状态信息写 stderr。\n */\nimport type { Runtime, ResultChunk } from '@aipack-ai/agent';\nimport chalk from 'chalk';\nimport { ChunkRenderer } from './render.js';\n\nexport async function runPrintMode(\n runtime: Runtime,\n request: Parameters<Runtime['run']>[0],\n): Promise<void> {\n const renderer = new ChunkRenderer({ toolStream: process.stderr });\n let error: string | undefined;\n let usage: { input?: number; output?: number } | undefined;\n\n try {\n for await (const chunk of runtime.stream(request) as AsyncGenerator<ResultChunk>) {\n if (chunk.type === 'error') error = chunk.content;\n if (chunk.type === 'done' && chunk.result?.usage) usage = chunk.result.usage;\n renderer.render(chunk);\n }\n } catch (err) {\n process.stderr.write(chalk.red(`错误: ${err instanceof Error ? err.message : String(err)}\\n`));\n process.exitCode = 1;\n return;\n }\n\n // token 用量写 stderr(保持 stdout 纯文本可管道)\n if (usage && (usage.input || usage.output)) {\n process.stderr.write(chalk.dim(`tokens: ↑${(usage.input ?? 0).toLocaleString()} ↓${(usage.output ?? 0).toLocaleString()}\\n`));\n }\n\n if (error) process.exitCode = 1;\n}\n","/**\n * 流式 chunk 的终端渲染(interactive / print 共用)\n */\nimport chalk from 'chalk';\nimport type { ResultChunk } from '@aipack-ai/agent';\n\nexport interface RenderOptions {\n /** 显示思考过程(默认折叠为省略提示) */\n showThinking?: boolean;\n /** 输出目标(默认 stdout;print 模式工具信息走 stderr 保持 stdout 纯文本) */\n toolStream?: NodeJS.WriteStream;\n}\n\nexport class ChunkRenderer {\n private thinkingShown = false;\n private inTool = false;\n\n constructor(private opts: RenderOptions = {}) {}\n\n render(chunk: ResultChunk): void {\n const err = this.opts.toolStream ?? process.stdout;\n switch (chunk.type) {\n case 'text':\n if (chunk.content) process.stdout.write(chunk.content);\n break;\n\n case 'thinking': {\n if (this.opts.showThinking && chunk.content) {\n process.stdout.write(chalk.dim(chunk.content));\n } else if (!this.thinkingShown) {\n this.thinkingShown = true;\n err.write(chalk.dim(' (思考中...)\\n'));\n }\n break;\n }\n\n case 'tool_start':\n this.inTool = true;\n err.write(chalk.cyan(`\\n⚙ ${chunk.toolName} `));\n break;\n\n case 'tool_end':\n if (this.inTool) {\n err.write(chunk.isError ? chalk.red(' ✗\\n') : chalk.green(' ✓\\n'));\n this.inTool = false;\n }\n break;\n\n case 'error':\n err.write(chalk.red(`\\n错误: ${chunk.content ?? '未知错误'}\\n`));\n break;\n\n case 'done':\n process.stdout.write('\\n');\n break;\n }\n }\n\n reset(): void {\n this.thinkingShown = false;\n this.inTool = false;\n }\n}\n","/**\n * json 模式(--mode json):全部流式事件以 JSON 行输出(stdout)。\n */\nimport type { Runtime, ResultChunk } from '@aipack-ai/agent';\n\nexport async function runJsonMode(\n runtime: Runtime,\n request: Parameters<Runtime['run']>[0],\n): Promise<void> {\n let sawError = false;\n try {\n for await (const chunk of runtime.stream(request) as AsyncGenerator<ResultChunk>) {\n if (chunk.type === 'error') sawError = true;\n const line = JSON.stringify({\n type: chunk.type,\n content: chunk.content,\n toolName: chunk.toolName,\n toolCallId: chunk.toolCallId,\n isError: chunk.isError,\n // done 类型:透出最终 Result 摘要(usage / stopReason / toolsUsed)供程序消费\n usage: chunk.result?.usage,\n stopReason: chunk.result?.stopReason,\n toolsUsed: chunk.result?.toolsUsed,\n timestamp: Date.now(),\n });\n process.stdout.write(`${line}\\n`);\n }\n if (sawError) process.exitCode = 1;\n } catch (err) {\n process.stdout.write(`${JSON.stringify({\n type: 'error',\n content: err instanceof Error ? err.message : String(err),\n timestamp: Date.now(),\n })}\\n`);\n process.exitCode = 1;\n }\n}\n","/**\n * 交互模式:REPL + 斜杠命令。\n *\n * 输入非斜杠开头的行 → 发送给 runtime 流式执行;\n * 流式期间可继续输入(提示排队/丢弃),Ctrl+C 中断当前运行,连按两次退出。\n *\n * 权限确认期间关闭主 readline,由 select 选择器(方向键)接管终端,\n * 确认结束重建 readline。\n */\nimport readline from 'node:readline';\nimport chalk from 'chalk';\nimport {\n getBuiltinModels,\n adaptAiModel,\n} from '@aipack-ai/agent';\nimport type {\n Runtime,\n ResultChunk,\n Request,\n ApprovalManager,\n SessionStorage,\n ThinkingLevel,\n PermissionRequest,\n} from '@aipack-ai/agent';\nimport type { Args } from '../args.js';\nimport type { ResolvedModel } from '../builder.js';\nimport { listSessionsByRecency } from '../builder.js';\nimport { ChunkRenderer } from './render.js';\nimport { ask } from '../prompt.js';\nimport { APP_NAME, VERSION } from '../version.js';\n\nexport interface InteractiveOptions {\n runtime: Runtime;\n sessionKey: string;\n model: ResolvedModel;\n args: Args;\n storage?: SessionStorage;\n approvalManager?: ApprovalManager;\n /** 启动时的初始消息(aipack \"帮我...\") */\n initialMessages?: string[];\n /** confirm 委托(cli.ts 创建;此处包装为\"关 rl → select → 重建 rl\"后生效) */\n confirmRef?: { fn: (req: PermissionRequest) => Promise<boolean> };\n /** 基础确认逻辑(含\"总是允许\"会话记忆),由 cli.ts 注入 */\n baseConfirm: (req: PermissionRequest) => Promise<boolean>;\n}\n\nconst VALID_THINKING = new Set(['off', 'minimal', 'low', 'medium', 'high', 'max']);\n\nexport async function runInteractiveMode(opts: InteractiveOptions): Promise<void> {\n const { runtime, sessionKey, model, args, storage, approvalManager } = opts;\n\n // --resume:先选会话\n let activeKey = sessionKey;\n if (args.resume && storage) {\n const picked = await pickSessionInteractively(storage, sessionKey);\n if (picked) activeKey = picked;\n }\n\n const renderer = new ChunkRenderer();\n let busy = false;\n let sigintCount = 0;\n\n /** 主循环存活 Promise:cleanup 时 resolve,进程由 cli.ts 收尾 */\n let finish!: () => void;\n const finished = new Promise<void>(resolve => { finish = resolve; });\n\n function cleanup(): void {\n finish();\n }\n\n // ── readline 生命周期(确认期间销毁重建,避免与 select 抢占 stdin)──\n\n let rl!: readline.Interface;\n /** rl.close() 来自\"确认前接管\"而非退出 */\n let recreating = false;\n\n function setupRl(): void {\n rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n prompt: chalk.blue('aipack> '),\n });\n\n rl.on('SIGINT', () => {\n if (busy) {\n console.log(chalk.yellow('\\n中断当前运行...'));\n runtime.abort(activeKey);\n return;\n }\n sigintCount++;\n if (sigintCount >= 2) {\n console.log(chalk.dim('\\n再见'));\n rl.close();\n } else {\n console.log(chalk.dim('(再按一次 Ctrl+C 退出)'));\n rl.prompt();\n setTimeout(() => { sigintCount = 0; }, 1500);\n }\n });\n\n rl.on('close', () => {\n if (!recreating) cleanup();\n });\n\n rl.on('line', onLine);\n rl.prompt();\n }\n\n // ── 请求执行 ──\n /** 会话内累计 token(跨多次 send) */\n let usageTotal = { input: 0, output: 0 };\n\n async function send(text: string): Promise<void> {\n if (!text.trim()) return;\n busy = true;\n sigintCount = 0;\n renderer.reset();\n\n const request: Request = {\n message: text,\n type: 'message',\n channel: 'cli',\n sessionKey: activeKey,\n ephemeral: args.noSession,\n };\n\n try {\n for await (const chunk of runtime.stream(request) as AsyncGenerator<ResultChunk>) {\n renderer.render(chunk);\n if (chunk.type === 'done' && chunk.result?.usage) {\n const u = chunk.result.usage as { input?: number; output?: number };\n usageTotal.input += u.input ?? 0;\n usageTotal.output += u.output ?? 0;\n }\n }\n if (usageTotal.input > 0 || usageTotal.output > 0) {\n console.log(chalk.dim(` tokens: ↑${usageTotal.input.toLocaleString()} ↓${usageTotal.output.toLocaleString()}(累计)`));\n }\n } catch (err) {\n console.log(chalk.red(`错误: ${err instanceof Error ? err.message : String(err)}`));\n } finally {\n busy = false;\n rl.prompt();\n }\n }\n\n // ── 斜杠命令 ──\n async function handleCommand(line: string): Promise<void> {\n const spaceIdx = line.indexOf(' ');\n const cmd = (spaceIdx === -1 ? line : line.slice(0, spaceIdx)).toLowerCase();\n const rest = spaceIdx === -1 ? '' : line.slice(spaceIdx + 1).trim();\n\n switch (cmd) {\n case '/help':\n printSlashHelp();\n break;\n\n case '/quit':\n case '/exit':\n rl.close();\n return;\n\n case '/model': {\n if (!rest) {\n console.log(chalk.dim(`当前模型: ${model.aiModel.provider}/${model.aiModel.id}`));\n console.log(chalk.dim('用法: /model provider/model-id(如 /model deepseek/deepseek-chat)'));\n break;\n }\n const slash = rest.indexOf('/');\n const provider = slash === -1 ? model.aiModel.provider : rest.slice(0, slash);\n const id = slash === -1 ? rest : rest.slice(slash + 1);\n const found = getBuiltinModels(provider).find(m => m.id === id);\n if (!found) {\n console.log(chalk.yellow(`未找到内置模型 ${provider}/${id},可用:`));\n console.log(getBuiltinModels(provider).map(m => ` ${m.id}`).join('\\n') || ' (无)');\n break;\n }\n runtime.setModel(adaptAiModel(found));\n model.aiModel = found;\n model.custom = false;\n console.log(chalk.green(`已切换到 ${provider}/${id}`));\n break;\n }\n\n case '/thinking': {\n if (!VALID_THINKING.has(rest)) {\n console.log(chalk.dim('用法: /thinking <off|minimal|low|medium|high|max>'));\n break;\n }\n runtime.setThinkingLevel(rest as ThinkingLevel);\n console.log(chalk.green(`思考级别: ${rest}`));\n break;\n }\n\n case '/system': {\n if (!rest) {\n console.log(chalk.dim('用法: /system <新的系统提示词>'));\n break;\n }\n runtime.setSystemPrompt(rest);\n console.log(chalk.green('系统提示词已更新'));\n break;\n }\n\n case '/session':\n console.log(`会话 key: ${chalk.cyan(activeKey)}`);\n console.log(`消息数: ${runtime.getMessages(activeKey).length}`);\n console.log(`持久化: ${args.noSession ? chalk.yellow('否(--no-session)') : chalk.green(storage ? '是' : '否(无存储)')}`);\n break;\n\n case '/sessions': {\n if (!storage) {\n console.log(chalk.yellow('当前为临时会话,无持久化存储'));\n break;\n }\n const sessions = await listSessionsByRecency(storage);\n if (sessions.length === 0) {\n console.log(chalk.dim('(无历史会话)'));\n break;\n }\n console.log(sessions.slice(0, 10).map((s, i) => `${s === activeKey ? chalk.green('▸ ') : ' '}${i + 1}. ${s}`).join('\\n'));\n console.log(chalk.dim('切换: 退出后用 aipack --session <key> 恢复'));\n break;\n }\n\n case '/clear':\n runtime.clearSession(activeKey);\n usageTotal = { input: 0, output: 0 };\n console.log(chalk.green('会话已清空(仅内存)'));\n break;\n\n case '/compact': {\n console.log(chalk.dim('压缩会话历史...'));\n const mode = await runtime.compact(activeKey);\n if (mode === null) {\n console.log(chalk.yellow('无可压缩内容(消息过少或压缩已通过 --no-compaction 关闭)'));\n } else {\n console.log(chalk.green(`已完成${mode === 'summary' ? '摘要压缩' : '截断压缩'},消息数: ${runtime.getMessages(activeKey).length}`));\n }\n break;\n }\n\n case '/tools':\n console.log(chalk.dim('内置工具: read, write, edit, bash, find, grep, ls'));\n console.log(chalk.dim('通过 --tools / --exclude-tools / --no-tools 配置启停'));\n break;\n\n case '/approvals': {\n if (!approvalManager) {\n console.log(chalk.yellow('审批未启用(在 aipack.config.js 中配置 approvals.enabled: true)'));\n break;\n }\n const pending = approvalManager.list();\n if (pending.length === 0) {\n console.log(chalk.dim('(无未决审批)'));\n break;\n }\n for (const p of pending) {\n console.log(`${chalk.cyan(p.id)} ${p.request.toolName} ${chalk.dim(new Date(p.createdAt).toLocaleString())}${p.restored ? chalk.yellow(' (孤儿)') : ''}`);\n }\n break;\n }\n\n case '/approve':\n case '/deny': {\n if (!approvalManager) {\n console.log(chalk.yellow('审批未启用'));\n break;\n }\n if (!rest) {\n console.log(chalk.dim(`用法: ${cmd} <审批单 id>`));\n break;\n }\n const ok = approvalManager.resolve(rest, cmd === '/approve');\n console.log(ok ? chalk.green('已生效') : chalk.yellow('审批单不存在或已结算'));\n break;\n }\n\n default:\n console.log(chalk.yellow(`未知命令: ${cmd}(/help 查看全部)`));\n }\n }\n\n function printSlashHelp(): void {\n console.log(`${chalk.bold('命令:')}\n /model [provider/id] 切换模型(无参显示当前)\n /thinking <级别> off/minimal/low/medium/high/max\n /system <文本> 替换系统提示词\n /session 当前会话信息\n /sessions 列出历史会话\n /clear 清空当前会话(仅内存)\n /compact 手动压缩会话历史(释放上下文空间)\n /approvals 未决审批单\n /approve <id> 批准\n /deny <id> 驳回\n /quit 退出(Ctrl+C 双击)`);\n }\n\n // ── 行输入分发 ──\n async function onLine(line: string): Promise<void> {\n const text = line.trim();\n if (!text) {\n rl.prompt();\n return;\n }\n if (busy) {\n console.log(chalk.dim('(运行中,输入被忽略;Ctrl+C 中断)'));\n rl.prompt();\n return;\n }\n if (text.startsWith('/')) {\n await handleCommand(text);\n rl.prompt();\n return;\n }\n await send(text);\n }\n\n // ── 权限确认:关 rl → select 接管 → 重建 rl ──\n if (opts.confirmRef) {\n opts.confirmRef.fn = async (req: PermissionRequest): Promise<boolean> => {\n recreating = true;\n rl.close();\n try {\n return await opts.baseConfirm(req);\n } finally {\n recreating = false;\n setupRl();\n }\n };\n }\n\n // ── 启动横幅 ──\n const modelLabel = `${model.aiModel.provider}/${model.aiModel.id}${model.custom ? chalk.yellow(' (自定义)') : ''}`;\n console.log(chalk.bold(`${APP_NAME} ${VERSION}`) + chalk.dim(` 会话: ${activeKey}${args.noSession ? ' (临时)' : ''}`));\n console.log(chalk.dim(`模型: ${modelLabel}`));\n console.log(chalk.dim('输入 /help 查看命令,Ctrl+C 中断运行,连按两次退出\\n'));\n\n setupRl();\n\n // ── 初始消息 ──\n if (opts.initialMessages && opts.initialMessages.length > 0) {\n await send(opts.initialMessages.join('\\n'));\n }\n\n // 保持存活直至用户退出(rl close → cleanup → resolve)\n await finished;\n}\n\n/** --resume 的会话选择器 */\nexport async function pickSessionInteractively(\n storage: SessionStorage,\n currentKey: string,\n): Promise<string | undefined> {\n const sessions = await listSessionsByRecency(storage);\n if (sessions.length === 0) {\n console.log(chalk.dim('(无历史会话,将新建)'));\n return undefined;\n }\n console.log(chalk.bold('选择会话:'));\n sessions.slice(0, 15).forEach((s, i) => {\n console.log(`${s === currentKey ? chalk.green('▸ ') : ' '}${i + 1}. ${s}`);\n });\n console.log(chalk.dim(' n. 新会话'));\n const answer = await ask('编号: ');\n if (answer === '' || answer.toLowerCase() === 'n') return undefined;\n const idx = Number.parseInt(answer, 10);\n if (Number.isInteger(idx) && idx >= 1 && idx <= Math.min(sessions.length, 15)) {\n return sessions[idx - 1];\n }\n return undefined;\n}\n","/**\n * 终端交互辅助:问题 / 确认\n */\nimport readline from 'node:readline';\n\nexport function ask(question: string): Promise<string> {\n return new Promise(resolve => {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n rl.question(question, answer => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\n/** y/N 确认;非 TTY 环境直接拒绝(保守) */\nexport async function confirm(question: string): Promise<boolean> {\n if (!process.stdin.isTTY) return false;\n const answer = await ask(`${question} [y/N] `);\n return answer === 'y' || answer === 'Y' || answer === 'yes';\n}\n\n/** 读取可读流全部内容(管道 stdin) */\nexport function readStreamAll(stream: NodeJS.ReadableStream): Promise<string> {\n return new Promise(resolve => {\n let data = '';\n stream.setEncoding?.('utf8');\n stream.on('data', chunk => { data += chunk; });\n stream.on('end', () => resolve(data));\n stream.on('error', () => resolve(data));\n });\n}\n","/**\n * 原生终端选择器(无第三方依赖)\n *\n * 渲染:\n * ? 问题文本\n * ❯ 选项一\n * 选项二\n *\n * 按键:↑/↓ 或 j/k 移动,1-9 直选,回车确认,Esc/q/Ctrl+C 取消。\n * 仅在 TTY 下可用;结束时恢复 raw mode 原状并清掉选项区、保留结果摘要。\n */\nimport chalk from 'chalk';\n\nexport interface SelectOption<T extends string = string> {\n label: string;\n value: T;\n}\n\nexport async function select<T extends string = string>(\n question: string,\n options: SelectOption<T>[],\n defaultIndex = 0,\n): Promise<T | null> {\n const stdin = process.stdin;\n const out = process.stdout;\n if (!stdin.isTTY || options.length === 0) return null;\n\n return new Promise<T | null>(resolve => {\n let selected = Math.min(Math.max(defaultIndex, 0), options.length - 1);\n\n const prevRaw = stdin.isRaw ?? false;\n stdin.setRawMode(true);\n stdin.setEncoding('utf8');\n stdin.resume();\n\n /** 光标约定:每次 render 前光标位于选项区首行行首 */\n function render(): void {\n for (let i = 0; i < options.length; i++) {\n const opt = options[i];\n const line = i === selected\n ? `${chalk.cyan('❯ ')}${chalk.bold(opt.label)}`\n : ` ${opt.label}`;\n out.write(`\\x1b[2K\\r${line}\\n`);\n }\n out.write(`\\x1b[${options.length}A`);\n }\n\n function finish(value: T | null): void {\n stdin.removeListener('data', onData);\n try { stdin.setRawMode(prevRaw); } catch { /* 进程退出竞态可忽略 */ }\n if (!prevRaw) stdin.pause();\n\n // 清除选项区,写一行结果摘要\n for (let i = 0; i < options.length; i++) out.write('\\x1b[2K\\r\\n');\n out.write(`\\x1b[${options.length}A`);\n const chosen = options.find(o => o.value === value);\n const summary = chosen\n ? chalk.green(`✓ ${chosen.label}`)\n : chalk.dim('已取消');\n out.write(`\\x1b[2K\\r ${summary}\\n`);\n\n resolve(value);\n }\n\n function onData(chunk: string): void {\n if (chunk.startsWith('\\x1b[A') || chunk === 'k') {\n selected = (selected - 1 + options.length) % options.length;\n } else if (chunk.startsWith('\\x1b[B') || chunk === 'j') {\n selected = (selected + 1) % options.length;\n } else if (chunk === '\\r' || chunk === '\\n') {\n finish(options[selected].value);\n return;\n } else if (chunk === '\\x1b' || chunk === '\\x1b\\x1b' || chunk === 'q' || chunk === '\\x03') {\n finish(null);\n return;\n } else if (/^[1-9]$/.test(chunk)) {\n const idx = Number(chunk) - 1;\n if (idx < options.length) {\n finish(options[idx].value);\n return;\n }\n return;\n } else {\n return; // 其余按键无操作(不重绘)\n }\n render();\n }\n\n out.write(`${chalk.yellow('?')} ${chalk.bold(question)}\\n`);\n render();\n stdin.on('data', onData);\n });\n}\n","/**\n * 终端交互式选择器 + 工具权限确认\n *\n * 替代 y/N 输入式确认:↑/↓(或 j/k)选择,回车确认,Esc/q/Ctrl+C 取消。\n * 数字键 1-9 直选。非 TTY 环境返回取消(保守拒绝)。\n */\nimport chalk from 'chalk';\nimport type { PermissionRequest } from '@aipack-ai/agent';\nimport { select } from './select.js';\n\nexport { select };\nexport type { SelectOption } from './select.js';\n\n// ─── 危险命令检测(bash 工具)────────────────────────────────────\n\n/** [模式, 说明]:命中的 shell 命令即使默认放行模式也需人工确认 */\nconst DANGEROUS_PATTERNS: Array<[RegExp, string]> = [\n // 递归删除根/家目录(rm -rf /、rm -rf ~、rm -rf /* 等;正常子目录不受影响)\n [/rm\\s+[^;|&]*[rf][^;|&]*\\s+(\\/|~|\\$HOME)(\\/?\\*|\\s|$)/, '递归删除根/家目录'],\n [/\\bsudo(\\s|$)/, '提权执行'],\n [/\\bmkfs(\\s|\\.)/, '格式化磁盘'],\n [/\\bdd\\s+[^;|]*of=\\/dev\\//, '写入磁盘设备'],\n [/>\\s*\\/dev\\/(sd|disk|nvme)/, '覆写磁盘设备'],\n [/(curl|wget)[^|;]*\\|\\s*(sudo\\s+)?(ba|z)?sh/, '管道执行远程脚本'],\n [/chmod\\s+-R\\s+777\\s+\\/(\\s|$)/, '根目录开放全部权限'],\n [/\\b(shutdown|reboot|halt|poweroff)\\b/, '关机/重启'],\n [/:\\s*\\(\\)\\s*\\{[^}]*\\}\\s*;\\s*:/, 'fork 炸弹'],\n];\n\n/** 返回危险原因;非危险命令返回 null */\nexport function isDangerousCommand(command: string): string | null {\n for (const [pattern, reason] of DANGEROUS_PATTERNS) {\n if (pattern.test(command)) return reason;\n }\n return null;\n}\n\n// ─── 工具权限确认(三选项 + 会话级记忆)──────────────────────────\n\nexport type ToolConfirmChoice = 'once' | 'always' | 'deny';\n\n/** 从工具参数提取简短摘要(bash 显示命令,文件工具显示路径) */\nfunction summarizeArgs(req: PermissionRequest): string {\n const args = req.args as Record<string, unknown> | undefined;\n if (!args || typeof args !== 'object') return '';\n const cmd = args.command;\n if (typeof cmd === 'string') return cmd.length > 60 ? `${cmd.slice(0, 60)}…` : cmd;\n const file = args.file ?? args.path;\n if (typeof file === 'string') return file;\n return '';\n}\n\nexport interface ToolConfirmHandlerOptions {\n /**\n * 自动放行低风险操作(默认 true):\n * - bash 的非危险命令静默放行,仅危险命令弹选择器\n * - false(--safe)时全部弹选择器\n */\n autoApproveSafe?: boolean;\n}\n\nexport function createToolConfirmHandler(\n options: ToolConfirmHandlerOptions = {},\n): (req: PermissionRequest) => Promise<boolean> {\n const autoApproveSafe = options.autoApproveSafe ?? true;\n /** 会话级\"总是允许\"记忆:key = 能力组合或工具名 */\n const alwaysAllowed = new Set<string>();\n\n return async (req: PermissionRequest): Promise<boolean> => {\n if (!process.stdin.isTTY) return false;\n\n const key = req.permissions.length > 0\n ? [...req.permissions].sort().join(',')\n : `tool:${req.toolName}`;\n if (alwaysAllowed.has(key)) return true;\n\n const args = req.args as Record<string, unknown> | undefined;\n const command = typeof args?.command === 'string' ? args.command : '';\n\n // 默认模式:bash 非危险命令自动放行(不打断用户)\n if (autoApproveSafe && command && !isDangerousCommand(command)) {\n return true;\n }\n\n const dangerReason = command ? isDangerousCommand(command) : null;\n const summary = command || summarizeArgs(req);\n const question = dangerReason\n ? `危险命令(${dangerReason}):${summary}`\n : summary\n ? `允许执行 ${req.toolName}:${summary}`\n : `允许执行 ${req.toolName}`;\n\n const choice = await select<ToolConfirmChoice>(question, [\n { label: '允许', value: 'once' },\n { label: '总是允许(本会话)', value: 'always' },\n { label: '拒绝', value: 'deny' },\n ]);\n\n if (choice === 'always') {\n alwaysAllowed.add(key);\n return true;\n }\n return choice === 'once';\n };\n}\n","/**\n * aipack CLI 主逻辑:子命令分发 + 模式路由\n * 可执行入口见 src/bin.ts(bin: dist/bin.js)\n */\nimport chalk from 'chalk';\nimport type { PermissionRequest } from '@aipack-ai/agent';\nimport { handleApprovalsCommand } from './commands/approvals.js';\nimport { listModels } from './commands/models.js';\nimport { parseArgs, printHelp } from './args.js';\nimport { buildRuntime } from './builder.js';\nimport { buildInitialMessage } from './initial-message.js';\nimport { runPrintMode } from './modes/print.js';\nimport { runJsonMode } from './modes/json.js';\nimport { runInteractiveMode } from './modes/interactive.js';\nimport { readStreamAll } from './prompt.js';\nimport { createToolConfirmHandler } from './confirm.js';\nimport { createRequest } from '@aipack-ai/agent';\nimport { VERSION } from './version.js';\n\nexport async function main(argv: string[]): Promise<number> {\n // ── 子命令:approvals ──\n if (argv[0] === 'approvals' || argv[0] === 'approval') {\n return handleApprovalsCommand(argv.slice(1));\n }\n\n // ── 参数解析 ──\n const args = parseArgs(argv);\n\n if (args.help) {\n printHelp();\n return 0;\n }\n if (args.version) {\n console.log(VERSION);\n return 0;\n }\n\n const errors = args.diagnostics.filter(d => d.type === 'error');\n if (errors.length > 0) {\n for (const e of errors) console.error(chalk.red(e.message));\n printHelp();\n return 1;\n }\n for (const w of args.diagnostics.filter(d => d.type === 'warning')) {\n console.error(chalk.yellow(w.message));\n }\n\n // ── --list-models ──\n if (args.listModels !== undefined) {\n return listModels(args.listModels);\n }\n\n // ── 管道 stdin(print / json 模式)──\n let stdinText: string | undefined;\n if ((args.print || args.mode === 'json') && !process.stdin.isTTY) {\n stdinText = await readStreamAll(process.stdin);\n }\n\n // ── 初始消息 ──\n const initial = await buildInitialMessage(args.messages, args.fileArgs, stdinText);\n\n const isNonInteractive = args.print || args.mode === 'json';\n if (isNonInteractive && !initial.text.trim() && initial.media.length === 0) {\n console.error(chalk.red('非交互模式需要提供消息(位置参数、@文件或管道 stdin)'));\n return 1;\n }\n\n // ── confirm 委托:选择式确认(方向键),交互模式接管后包装 rl 重建 ──\n // 默认自动放行非危险命令;--safe 时全部人工确认\n const toolConfirm = createToolConfirmHandler({ autoApproveSafe: !args.safe });\n const confirmRef: { fn: (req: PermissionRequest) => Promise<boolean> } = {\n fn: req => toolConfirm(req),\n };\n\n // ── 构建 Runtime ──\n let built;\n try {\n built = await buildRuntime({\n args,\n cwd: process.cwd(),\n confirmFn: req => confirmRef.fn(req),\n });\n } catch (err) {\n console.error(chalk.red(`初始化失败: ${err instanceof Error ? err.message : String(err)}`));\n return 1;\n }\n\n // ── 模式分发 ──\n try {\n if (args.mode === 'json') {\n const request = createRequest(initial.text || '(空)', {\n channel: 'cli',\n sessionKey: built.sessionKey,\n ephemeral: args.noSession,\n media: initial.media,\n });\n await runJsonMode(built.runtime, request);\n } else if (args.print) {\n const request = createRequest(initial.text || '(空)', {\n channel: 'cli',\n sessionKey: built.sessionKey,\n ephemeral: args.noSession,\n media: initial.media,\n });\n await runPrintMode(built.runtime, request);\n } else {\n await runInteractiveMode({\n runtime: built.runtime,\n sessionKey: built.sessionKey,\n model: built.model,\n args,\n storage: built.storage,\n approvalManager: built.approvalManager,\n initialMessages: args.messages.length > 0 ? [initial.text] : [],\n confirmRef,\n baseConfirm: toolConfirm,\n });\n }\n } finally {\n built.approvalManager?.close();\n await built.runtime.close();\n }\n\n return process.exitCode === 1 ? 1 : 0;\n}\n","/**\n * approvals 子命令:跨进程查看/结算审批单(基于 FileApprovalStore)。\n *\n * 语义:审批单由启用 approvals 的运行进程创建(pending 时落盘)。\n * 本命令直接经 store 结算文件(同进程内存等待方无法被唤醒——跨进程审批\n * 面板场景;交互会话内请用 /approve、/deny)。\n */\nimport path from 'node:path';\nimport chalk from 'chalk';\nimport { FileApprovalStore, createApprovalManager } from '@aipack-ai/agent';\nimport type { StoredApproval } from '@aipack-ai/agent';\nimport { defaultConfigDir } from '../version.js';\n\nfunction createStore(): FileApprovalStore {\n return new FileApprovalStore({\n baseDir: path.join(defaultConfigDir(), 'approvals'),\n });\n}\n\nexport async function handleApprovalsCommand(args: string[]): Promise<number> {\n const [sub, ...rest] = args;\n\n if (!sub || sub === 'help' || sub === '--help') {\n printUsage();\n return 0;\n }\n\n const store = createStore();\n\n if (sub === 'list') {\n const pending = await store.load();\n if (pending.length === 0) {\n console.log(chalk.dim('(无未决审批单)'));\n return 0;\n }\n for (const p of pending) {\n printApproval(p);\n }\n return 0;\n }\n\n if (sub === 'approve' || sub === 'deny') {\n const id = rest[0];\n if (!id) {\n console.error(chalk.red(`用法: aipack approvals ${sub} <id>`));\n return 1;\n }\n // 经 ApprovalManager 走 restore + resolve,复用统一结算/审计路径\n const manager = createApprovalManager({ store });\n await manager.restore();\n const ok = manager.resolve(id, sub === 'approve');\n manager.close();\n if (!ok) {\n console.error(chalk.yellow(`审批单 ${id} 不存在或已结算`));\n return 1;\n }\n console.log(chalk.green(`已${sub === 'approve' ? '批准' : '驳回'} ${id}`));\n return 0;\n }\n\n printUsage();\n console.error(chalk.red(`未知子命令: ${sub}`));\n return 1;\n}\n\nfunction printApproval(p: StoredApproval): void {\n const created = new Date(p.createdAt).toLocaleString();\n const expires = p.expiresAt ? chalk.dim(` 过期 ${new Date(p.expiresAt).toLocaleTimeString()}`) : '';\n console.log(`${chalk.cyan(p.id)} ${chalk.bold(p.toolName)} ${chalk.dim(created)}${expires}`);\n if (p.permissions.length > 0) {\n console.log(chalk.dim(` 能力: ${p.permissions.join(', ')}`));\n }\n const argsStr = JSON.stringify(p.args);\n if (argsStr && argsStr !== '{}') {\n console.log(chalk.dim(` 参数: ${argsStr.length > 120 ? `${argsStr.slice(0, 120)}…` : argsStr}`));\n }\n}\n\nfunction printUsage(): void {\n console.log(`用法:\n aipack approvals list 列出未决审批单\n aipack approvals approve <id> 批准\n aipack approvals deny <id> 驳回`);\n}\n","/**\n * --list-models:列出内置目录模型(可搜索),标注 API Key 配置状态。\n */\nimport chalk from 'chalk';\nimport { getBuiltinProviders, getBuiltinModels, hasProviderConfigured } from '@aipack-ai/agent';\n\nexport function listModels(search?: string | true): number {\n const term = typeof search === 'string' ? search.toLowerCase() : undefined;\n let total = 0;\n\n for (const provider of getBuiltinProviders()) {\n const models = getBuiltinModels(provider.id);\n const matched = term\n ? models.filter(m =>\n m.id.toLowerCase().includes(term) ||\n m.name.toLowerCase().includes(term) ||\n provider.id.includes(term))\n : models;\n if (matched.length === 0) continue;\n\n const configured = hasProviderConfigured(provider.id);\n const badge = configured ? chalk.green('✓') : chalk.dim('·');\n console.log(`${badge} ${chalk.bold(provider.name)} ${chalk.dim(`(${provider.id})`)}`);\n\n for (const m of matched) {\n const flags = [\n m.reasoning ? chalk.dim('推理') : null,\n `${(m.contextWindow / 1000) | 0}k`,\n ].filter(Boolean).join(' ');\n console.log(` ${m.id.padEnd(44)} ${chalk.dim(flags)}`);\n total++;\n }\n }\n\n console.log(chalk.dim(`\\n共 ${total} 个模型。✓ = 已配置 API Key(${getEnvHint()})`));\n return 0;\n}\n\nfunction getEnvHint(): string {\n const provider = getBuiltinProviders().find(p => hasProviderConfigured(p.id));\n return provider ? `${provider.envVar} 已设置` : '未检测到任何 API Key';\n}\n"],"mappings":"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","names":["path","fs","path","path","fs","fs","path","chalk","chalk","readline","chalk","getBuiltinModels","adaptAiModel","readline","chalk","getBuiltinModels","adaptAiModel","chalk","chalk","path","chalk","FileApprovalStore","createApprovalManager","FileApprovalStore","path","chalk","createApprovalManager","chalk","getBuiltinProviders","getBuiltinModels","hasProviderConfigured","chalk"]}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { ThinkingLevel, Tool, Runtime, SessionStorage, ApprovalManager, AiModel, PermissionRequest } from '@aipack-ai/agent';
2
+ import { ContextCompressionTransformer } from '@aipack-ai/compression';
2
3
 
3
4
  /**
4
5
  * CLI 参数解析与帮助文本(参考 pi 的 args.ts,适配 aipack)
@@ -28,6 +29,10 @@ interface Args {
28
29
  listModels?: string | true;
29
30
  /** 保守模式:写文件与 shell 全部人工确认 */
30
31
  safe?: boolean;
32
+ /** 关闭上下文压缩(内置摘要压缩与五级压缩 transformer 均不启用) */
33
+ noCompaction?: boolean;
34
+ /** 压缩配置文件路径(JSON,DeepPartial<CompressionConfig> 结构,叠加在默认配置上) */
35
+ compactionConfig?: string;
31
36
  /** 位置参数(用户消息) */
32
37
  messages: string[];
33
38
  /** @file 引用 */
@@ -102,6 +107,8 @@ interface BuiltRuntime {
102
107
  approvalManager?: ApprovalManager;
103
108
  model: ResolvedModel;
104
109
  config: AipackCliConfig;
110
+ /** 五级压缩转换器(--no-compaction 时为 undefined) */
111
+ compressionTransformer?: ContextCompressionTransformer;
105
112
  }
106
113
  declare function buildRuntime(options: BuildRuntimeOptions): Promise<BuiltRuntime>;
107
114
 
package/dist/index.js CHANGED
@@ -26,7 +26,7 @@ import {
26
26
  select,
27
27
  selectTools,
28
28
  writeTool
29
- } from "./chunk-LXRCYMRS.js";
29
+ } from "./chunk-TPMRQPLX.js";
30
30
  export {
31
31
  APP_NAME,
32
32
  BUILTIN_TOOLS,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aipack-ai/cli",
3
- "version": "0.0.2",
3
+ "version": "1.0.0",
4
4
  "description": "aipack CLI - 基于 @aipack-ai/agent 的终端 AI 助手",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -31,7 +31,8 @@
31
31
  },
32
32
  "dependencies": {
33
33
  "chalk": "^5.3.0",
34
- "@aipack-ai/agent": "0.0.1"
34
+ "@aipack-ai/agent": "1.0.0",
35
+ "@aipack-ai/compression": "1.0.0"
35
36
  },
36
37
  "devDependencies": {
37
38
  "@types/node": "^20.12.0",
@@ -41,8 +42,9 @@
41
42
  },
42
43
  "scripts": {
43
44
  "build": "tsup",
44
- "prebuild": "pnpm --filter @aipack-ai/agent build",
45
+ "prebuild": "[ -f ../agent/dist/index.d.ts ] || pnpm --filter @aipack-ai/agent build",
45
46
  "typecheck": "tsc --noEmit",
47
+ "test": "node --import tsx --test test/*.test.ts",
46
48
  "dev": "tsx src/bin.ts"
47
49
  }
48
50
  }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/version.ts","../package.json","../src/args.ts","../src/tools.ts","../src/builder.ts","../src/initial-message.ts","../src/modes/print.ts","../src/modes/render.ts","../src/modes/json.ts","../src/modes/interactive.ts","../src/prompt.ts","../src/select.ts","../src/confirm.ts","../src/cli.ts","../src/commands/approvals.ts","../src/commands/models.ts"],"sourcesContent":["/**\n * CLI 元信息与目录约定\n */\nimport os from 'node:os';\nimport path from 'node:path';\nimport pkg from '../package.json';\n\n/** 命令名:优先取 bin 名称(aipack),兜底包名去 scope */\nexport const APP_NAME =\n Object.keys(pkg.bin ?? {})[0] ?? pkg.name.replace(/^@[^/]+\\//, '');\nexport const VERSION = pkg.version;\n\n/** 全局配置目录(默认 ~/.aipack,可用 AIPACK_CONFIG_DIR 覆盖) */\nexport function defaultConfigDir(): string {\n return process.env.AIPACK_CONFIG_DIR ?? path.join(os.homedir(), '.aipack');\n}\n\n/**\n * CLI 会话存储目录(按工作目录分组):\n * ~/.aipack/cli-sessions/<cwd 安全编码>/<sessionKey>.json\n */\nexport function defaultSessionDir(cwd: string): string {\n return path.join(defaultConfigDir(), 'cli-sessions', encodeDir(cwd));\n}\n\n/** 将路径编码为安全目录名 */\nexport function encodeDir(p: string): string {\n return p.replace(/[^a-zA-Z0-9_-]/g, '_');\n}\n","{\n \"name\": \"@aipack-ai/cli\",\n \"version\": \"0.0.2\",\n \"description\": \"aipack CLI - 基于 @aipack-ai/agent 的终端 AI 助手\",\n \"type\": \"module\",\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"bin\": {\n \"aipack\": \"dist/bin.js\"\n },\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\"\n },\n \"./package.json\": \"./package.json\"\n },\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"prebuild\": \"pnpm --filter @aipack-ai/agent build\",\n \"typecheck\": \"tsc --noEmit\",\n \"dev\": \"tsx src/bin.ts\"\n },\n \"keywords\": [\n \"cli\",\n \"ai\",\n \"agent\",\n \"llm\",\n \"aipack\"\n ],\n \"license\": \"MIT\",\n \"engines\": {\n \"node\": \">=18.19.0\"\n },\n \"dependencies\": {\n \"@aipack-ai/agent\": \"workspace:*\",\n \"chalk\": \"^5.3.0\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.12.0\",\n \"tsup\": \"^8.5.1\",\n \"tsx\": \"^4.16.0\",\n \"typescript\": \"^5.5.0\"\n }\n}\n","/**\n * CLI 参数解析与帮助文本(参考 pi 的 args.ts,适配 aipack)\n */\nimport type { ThinkingLevel } from '@aipack-ai/agent';\nimport { APP_NAME, VERSION } from './version.js';\n\nexport type Mode = 'text' | 'json';\n\nexport interface Args {\n provider?: string;\n model?: string;\n apiKey?: string;\n systemPrompt?: string;\n appendSystemPrompt?: string[];\n thinking?: ThinkingLevel;\n continue?: boolean;\n resume?: boolean;\n help?: boolean;\n version?: boolean;\n mode?: Mode;\n name?: string;\n noSession?: boolean;\n session?: string;\n sessionDir?: string;\n tools?: string[];\n excludeTools?: string[];\n noTools?: boolean;\n print?: boolean;\n listModels?: string | true;\n /** 保守模式:写文件与 shell 全部人工确认 */\n safe?: boolean;\n /** 位置参数(用户消息) */\n messages: string[];\n /** @file 引用 */\n fileArgs: string[];\n diagnostics: Array<{ type: 'warning' | 'error'; message: string }>;\n}\n\nconst VALID_THINKING_LEVELS = ['off', 'minimal', 'low', 'medium', 'high', 'max'] as const;\n\nexport function isValidThinkingLevel(level: string): level is ThinkingLevel {\n return (VALID_THINKING_LEVELS as readonly string[]).includes(level);\n}\n\nexport function parseArgs(args: string[]): Args {\n const result: Args = {\n messages: [],\n fileArgs: [],\n diagnostics: [],\n };\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n\n if (arg === '--help' || arg === '-h') {\n result.help = true;\n } else if (arg === '--version' || arg === '-v') {\n result.version = true;\n } else if (arg === '--mode' && i + 1 < args.length) {\n const mode = args[++i];\n if (mode === 'text' || mode === 'json') {\n result.mode = mode;\n } else {\n result.diagnostics.push({ type: 'error', message: `无效的 mode: ${mode}(可选 text / json)` });\n }\n } else if (arg === '--continue' || arg === '-c') {\n result.continue = true;\n } else if (arg === '--resume' || arg === '-r') {\n result.resume = true;\n } else if (arg === '--provider' && i + 1 < args.length) {\n result.provider = args[++i];\n } else if (arg === '--model' && i + 1 < args.length) {\n result.model = args[++i];\n } else if (arg === '--api-key' && i + 1 < args.length) {\n result.apiKey = args[++i];\n } else if (arg === '--system-prompt' && i + 1 < args.length) {\n result.systemPrompt = args[++i];\n } else if (arg === '--append-system-prompt' && i + 1 < args.length) {\n result.appendSystemPrompt = result.appendSystemPrompt ?? [];\n result.appendSystemPrompt.push(args[++i]);\n } else if (arg === '--thinking' && i + 1 < args.length) {\n const level = args[++i];\n if (isValidThinkingLevel(level)) {\n result.thinking = level;\n } else {\n result.diagnostics.push({\n type: 'warning',\n message: `无效的思考级别 \"${level}\"。可选: ${VALID_THINKING_LEVELS.join(', ')}`,\n });\n }\n } else if (arg === '--name' || arg === '-n') {\n if (i + 1 < args.length) {\n result.name = args[++i];\n } else {\n result.diagnostics.push({ type: 'error', message: '--name 需要一个值' });\n }\n } else if (arg === '--no-session') {\n result.noSession = true;\n } else if (arg === '--session' && i + 1 < args.length) {\n result.session = args[++i];\n } else if (arg === '--session-dir' && i + 1 < args.length) {\n result.sessionDir = args[++i];\n } else if ((arg === '--tools' || arg === '-t') && i + 1 < args.length) {\n result.tools = args[++i].split(',').map(s => s.trim()).filter(Boolean);\n } else if ((arg === '--exclude-tools' || arg === '-xt') && i + 1 < args.length) {\n result.excludeTools = args[++i].split(',').map(s => s.trim()).filter(Boolean);\n } else if (arg === '--no-tools' || arg === '-nt') {\n result.noTools = true;\n } else if (arg === '--safe') {\n result.safe = true;\n } else if (arg === '--print' || arg === '-p') {\n result.print = true;\n const next = args[i + 1];\n if (next !== undefined && !next.startsWith('@') && !next.startsWith('-')) {\n result.messages.push(next);\n i++;\n }\n } else if (arg === '--list-models') {\n const next = args[i + 1];\n if (next !== undefined && !next.startsWith('-') && !next.startsWith('@')) {\n result.listModels = next;\n i++;\n } else {\n result.listModels = true;\n }\n } else if (arg.startsWith('@')) {\n result.fileArgs.push(arg.slice(1));\n } else if (arg.startsWith('--')) {\n result.diagnostics.push({ type: 'error', message: `未知选项: ${arg}` });\n } else if (arg.startsWith('-') && arg !== '-') {\n result.diagnostics.push({ type: 'error', message: `未知选项: ${arg}` });\n } else {\n result.messages.push(arg);\n }\n }\n\n return result;\n}\n\nexport function printHelp(): void {\n console.log(`${APP_NAME} ${VERSION} - 基于 @aipack-ai/agent 的终端 AI 助手\n\n${'用法:'}\n ${APP_NAME} [选项] [@文件...] [消息...]\n\n${'子命令:'}\n ${APP_NAME} approvals list 列出未决审批单\n ${APP_NAME} approvals approve <id> 批准审批单\n ${APP_NAME} approvals deny <id> 驳回审批单\n ${APP_NAME} --list-models [搜索] 列出可用模型\n\n${'模式:'}\n (默认) 交互模式(REPL)\n --print, -p [消息] 非交互:处理一次提示后退出(支持管道 stdin)\n --mode json 以 JSON 行输出全部流式事件\n\n${'模型选项:'}\n --provider <名称> 提供商(openai/deepseek/anthropic/google...)\n --model <id> 模型 ID,支持 provider/id 组合写法\n --api-key <key> API Key(覆盖环境变量)\n --thinking <级别> 思考级别: off/minimal/low/medium/high/max\n\n${'会话选项:'}\n --continue, -c 继续当前目录最近的会话\n --resume, -r 浏览并选择历史会话\n --session <名称> 使用指定会话\n --name, -n <名称> 为新会话命名\n --session-dir <目录> 自定义会话存储目录\n --no-session 临时会话(不持久化)\n\n${'工具选项:'}\n --tools, -t <列表> 工具白名单(逗号分隔)\n --exclude-tools, -xt <列表> 工具黑名单(逗号分隔)\n --no-tools, -nt 禁用全部工具\n --safe 保守模式:写文件/shell 全部人工确认\n\n 内置工具: read, write, edit, bash\n 默认权限: 读写文件静默放行(工作区范围内);bash 仅危险命令\n (sudo、rm -rf ~、磁盘写入、远程脚本管道等)需确认\n\n${'其他:'}\n --system-prompt <文本> 替换默认系统提示词\n --append-system-prompt <文本> 追加系统提示词(可多次)\n --help, -h 显示帮助\n --version, -v 显示版本\n\n${'示例:'}\n # 交互模式\n ${APP_NAME}\n\n # 非交互单次提问(支持管道)\n cat README.md | ${APP_NAME} -p \"总结这段文本\"\n\n # 指定模型\n ${APP_NAME} --provider deepseek --model deepseek-chat \"你好\"\n\n # provider/id 组合写法\n ${APP_NAME} --model anthropic/claude-sonnet-4-20250514 \"帮我重构代码\"\n\n # 附带文件上下文\n ${APP_NAME} @package.json \"分析这个文件的依赖\"\n\n # 继续上次会话\n ${APP_NAME} -c \"我们刚才聊到哪里了?\"\n\n # 只读模式\n ${APP_NAME} --tools read -p \"审查 src/ 下的代码\"\n\n${'环境变量:'}\n OPENAI_API_KEY / DEEPSEEK_API_KEY / ANTHROPIC_API_KEY / GOOGLE_API_KEY ...\n AIPACK_CONFIG_DIR 配置目录(默认 ~/.aipack)\n`);\n}\n","/**\n * 内置工具:read / write / edit / bash\n *\n * 参考 pi 的 coding-agent 默认工具集。每个工具声明 permissions 能力,\n * 供框架级 PermissionPolicy 裁决(如 fs:write → confirm / pending)。\n */\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { spawn } from 'node:child_process';\nimport type { Tool, ToolResult } from '@aipack-ai/agent';\n\n/** 工作区根目录:文件路径解析的基准(防止越界访问任意路径) */\nexport const workspaceRoot = process.cwd();\n\nfunction resolveInWorkspace(p: string): string {\n const abs = path.resolve(workspaceRoot, p);\n if (!abs.startsWith(workspaceRoot)) {\n throw new Error(`路径越界:${p}(工作区:${workspaceRoot})`);\n }\n return abs;\n}\n\nfunction textResult(text: string, details?: unknown): ToolResult {\n return { content: [{ type: 'text', text }], details: details ?? {} };\n}\n\nfunction errorResult(message: string): ToolResult {\n return {\n content: [{ type: 'text', text: `错误: ${message}` }],\n details: { error: message },\n };\n}\n\n/** 单文件读取上限(字符),超出截断 */\nconst MAX_READ_CHARS = 100_000;\n\n// ─── read ─────────────────────────────────────────────────────────\n\nexport const readTool: Tool = {\n name: 'read',\n description: '读取文件内容。返回文本内容,超长自动截断。',\n parameters: {\n type: 'object',\n properties: {\n file: { type: 'string', description: '文件路径(相对工作区)' },\n offset: { type: 'number', description: '起始行号(从 1 开始,可选)' },\n limit: { type: 'number', description: '读取行数(可选)' },\n },\n required: ['file'],\n },\n permissions: ['fs:read'],\n async execute(_id, rawArgs) {\n const args = rawArgs as { file: string; offset?: number; limit?: number };\n try {\n const abs = resolveInWorkspace(args.file);\n let content = await fs.readFile(abs, 'utf8');\n if (args.offset !== undefined || args.limit !== undefined) {\n const lines = content.split('\\n');\n const start = Math.max(0, (args.offset ?? 1) - 1);\n const end = args.limit !== undefined ? start + args.limit : lines.length;\n content = lines.slice(start, end).join('\\n');\n }\n if (content.length > MAX_READ_CHARS) {\n content = content.slice(0, MAX_READ_CHARS) + `\\n...[截断,共 ${content.length} 字符]`;\n }\n return textResult(content, { file: args.file, truncated: content.length >= MAX_READ_CHARS });\n } catch (err) {\n return errorResult(String(err instanceof Error ? err.message : err));\n }\n },\n};\n\n// ─── write ────────────────────────────────────────────────────────\n\nexport const writeTool: Tool = {\n name: 'write',\n description: '写入文件(创建或覆盖)。自动创建父目录。',\n parameters: {\n type: 'object',\n properties: {\n file: { type: 'string', description: '文件路径(相对工作区)' },\n content: { type: 'string', description: '完整文件内容' },\n },\n required: ['file', 'content'],\n },\n permissions: ['fs:write'],\n async execute(_id, rawArgs) {\n const args = rawArgs as { file: string; content: string };\n try {\n const abs = resolveInWorkspace(args.file);\n await fs.mkdir(path.dirname(abs), { recursive: true });\n await fs.writeFile(abs, args.content, 'utf8');\n return textResult(`已写入 ${args.file}(${args.content.length} 字符)`, { file: args.file });\n } catch (err) {\n return errorResult(String(err instanceof Error ? err.message : err));\n }\n },\n};\n\n// ─── edit ─────────────────────────────────────────────────────────\n\nexport const editTool: Tool = {\n name: 'edit',\n description: '编辑文件:将 oldString 的首次出现替换为 newString。oldString 必须唯一匹配。',\n parameters: {\n type: 'object',\n properties: {\n file: { type: 'string', description: '文件路径(相对工作区)' },\n oldString: { type: 'string', description: '被替换的文本(须在文件中唯一)' },\n newString: { type: 'string', description: '替换后的文本' },\n },\n required: ['file', 'oldString', 'newString'],\n },\n permissions: ['fs:write'],\n async execute(_id, rawArgs) {\n const args = rawArgs as { file: string; oldString: string; newString: string };\n try {\n const abs = resolveInWorkspace(args.file);\n const content = await fs.readFile(abs, 'utf8');\n const first = content.indexOf(args.oldString);\n if (first === -1) {\n return errorResult(`在 ${args.file} 中未找到 oldString`);\n }\n if (content.indexOf(args.oldString, first + 1) !== -1) {\n return errorResult(`oldString 在 ${args.file} 中出现多次,请提供更长的上下文使其唯一`);\n }\n const updated = content.slice(0, first) + args.newString + content.slice(first + args.oldString.length);\n await fs.writeFile(abs, updated, 'utf8');\n return textResult(`已编辑 ${args.file}`, { file: args.file });\n } catch (err) {\n return errorResult(String(err instanceof Error ? err.message : err));\n }\n },\n};\n\n// ─── bash ─────────────────────────────────────────────────────────\n\nfunction runShell(command: string, timeoutMs: number): Promise<{ stdout: string; stderr: string; code: number }> {\n return new Promise(resolve => {\n const child = spawn(command, {\n shell: process.env.SHELL ?? '/bin/bash',\n cwd: workspaceRoot,\n env: { ...process.env, AIPACK_CLI: 'true' },\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n let stdout = '';\n let stderr = '';\n let settled = false;\n\n const timer = setTimeout(() => {\n if (!settled) {\n settled = true;\n child.kill('SIGKILL');\n resolve({ stdout, stderr: stderr + `\\n[命令超时(${timeoutMs}ms)被终止]`, code: 124 });\n }\n }, timeoutMs);\n\n child.stdout.on('data', d => { stdout += d.toString(); });\n child.stderr.on('data', d => { stderr += d.toString(); });\n child.on('close', code => {\n if (!settled) {\n settled = true;\n clearTimeout(timer);\n resolve({ stdout, stderr, code: code ?? 0 });\n }\n });\n child.on('error', err => {\n if (!settled) {\n settled = true;\n clearTimeout(timer);\n resolve({ stdout, stderr: String(err), code: -1 });\n }\n });\n });\n}\n\nexport const bashTool: Tool = {\n name: 'bash',\n description: '在工作区执行 shell 块命令并返回输出。适用于文件搜索、构建、测试等操作。',\n parameters: {\n type: 'object',\n properties: {\n command: { type: 'string', description: '要执行的命令' },\n timeoutMs: { type: 'number', description: '超时毫秒数(默认 60000)' },\n },\n required: ['command'],\n },\n permissions: ['shell:exec'],\n async execute(_id, rawArgs) {\n const args = rawArgs as { command: string; timeoutMs?: number };\n const timeout = args.timeoutMs ?? 60_000;\n try {\n const { stdout, stderr, code } = await runShell(args.command, timeout);\n const parts: string[] = [];\n if (stdout.trim()) parts.push(`[stdout]\\n${stdout.slice(0, MAX_READ_CHARS)}`);\n if (stderr.trim()) parts.push(`[stderr]\\n${stderr.slice(0, MAX_READ_CHARS)}`);\n parts.push(`[退出码 ${code}]`);\n return textResult(parts.join('\\n'), { command: args.command, code });\n } catch (err) {\n return errorResult(String(err instanceof Error ? err.message : err));\n }\n },\n};\n\n// ─── 工具集组装 ───────────────────────────────────────────────────\n\nexport const BUILTIN_TOOLS: Tool[] = [readTool, writeTool, editTool, bashTool];\n\n/**\n * 按白名单/黑名单过滤内置工具。\n * - tools: 仅保留白名单中的工具\n * - excludeTools: 移除黑名单中的工具\n * - noTools: 返回空数组\n */\nexport function selectTools(options: {\n tools?: string[];\n excludeTools?: string[];\n noTools?: boolean;\n}): Tool[] {\n if (options.noTools) return [];\n let selected = [...BUILTIN_TOOLS];\n if (options.tools && options.tools.length > 0) {\n const allow = new Set(options.tools);\n selected = selected.filter(t => allow.has(t.name));\n }\n if (options.excludeTools && options.excludeTools.length > 0) {\n const deny = new Set(options.excludeTools);\n selected = selected.filter(t => !deny.has(t.name));\n }\n return selected;\n}\n","/**\n * Runtime 构建器:把 CLI 参数解析结果组装成可运行的 Runtime。\n *\n * 职责:\n * 1. 加载 aipack.config.js(可选:approvals.enabled 等)\n * 2. 解析模型(--model 支持 provider/id;未配置时自动探测有 API Key 的提供商)\n * 3. 会话存储与 sessionKey 选择(--continue 找最新 / --session / --name / 自动生成)\n * 4. 权限策略(fs:read 放行;fs:write / shell:exec 按配置走 confirm 或 pending 审批)\n */\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport {\n createRuntime,\n adaptAiModel,\n createStreamFnFromAi,\n getBuiltinModel,\n getBuiltinModels,\n getBuiltinProviders,\n BUILTIN_PROVIDERS,\n hasProviderConfigured,\n createFileSessionStorage,\n createPermissionPolicy,\n createApprovalManager,\n FileApprovalStore,\n} from '@aipack-ai/agent';\nimport type {\n Runtime,\n Tool,\n SessionStorage,\n ApprovalManager,\n PermissionRequest,\n AiModel,\n PermissionPolicy,\n} from '@aipack-ai/agent';\nimport type { Args } from './args.js';\nimport { selectTools } from './tools.js';\nimport { defaultSessionDir, defaultConfigDir, VERSION } from './version.js';\n\n// ─── 配置文件 ─────────────────────────────────────────────────────\n\nexport interface AipackCliConfig {\n approvals?: {\n /** 是否启用异步审批(pending 决策 + ApprovalManager)。默认 false(内联 confirm) */\n enabled?: boolean;\n /** 触发审批的能力列表(默认 fs:write 与 shell:exec) */\n capabilities?: string[];\n };\n /** 额外权限规则(追加在内置规则之前,优先裁决) */\n permissionRules?: Array<{\n toolName?: string;\n permission?: string;\n decision: 'allow' | 'deny' | 'confirm' | 'pending';\n }>;\n}\n\nexport async function loadConfig(cwd: string): Promise<AipackCliConfig> {\n for (const file of ['aipack.config.js', 'aipack.config.mjs']) {\n const full = path.join(cwd, file);\n try {\n await fs.access(full);\n const mod = await import(pathToFileURL(full).href);\n const config = (mod.default ?? mod) as AipackCliConfig;\n return config ?? {};\n } catch {\n // 文件不存在或加载失败 → 继续尝试 / 返回空配置\n }\n }\n return {};\n}\n\n// ─── 模型解析 ─────────────────────────────────────────────────────\n\nexport interface ResolvedModel {\n aiModel: AiModel;\n /** 是否为目录外自定义模型 */\n custom: boolean;\n}\n\n/** 从 --model \"provider/id\" 或 --provider + --model 解析 */\nfunction splitModelSpec(args: Args): { provider?: string; modelId?: string } {\n if (args.model && args.model.includes('/')) {\n const idx = args.model.indexOf('/');\n return { provider: args.model.slice(0, idx), modelId: args.model.slice(idx + 1) };\n }\n return { provider: args.provider, modelId: args.model };\n}\n\n/** 第一个已配置 API Key 的内置提供商 */\nfunction detectDefaultProvider(): { id: string; modelId: string } {\n for (const p of getBuiltinProviders()) {\n if (hasProviderConfigured(p.id)) {\n const models = getBuiltinModels(p.id);\n if (models.length > 0) return { id: p.id, modelId: models[0].id };\n }\n }\n return { id: 'openai', modelId: 'gpt-4o-mini' };\n}\n\n/** 为目录外模型构造最小可用的 ai Model(推断 API 类型与 baseUrl) */\nfunction buildCustomModel(providerId: string, modelId: string): AiModel {\n const meta = BUILTIN_PROVIDERS.find(p => p.id === providerId);\n const api = providerId === 'anthropic' ? 'anthropic-messages' : 'openai-completions';\n return {\n id: modelId,\n name: modelId,\n provider: providerId,\n api,\n baseUrl: meta?.baseUrl,\n reasoning: false,\n input: ['text'],\n contextWindow: 128000,\n maxTokens: 16384,\n } as AiModel;\n}\n\nexport function resolveModel(args: Args): ResolvedModel {\n const spec = splitModelSpec(args);\n const fallback = detectDefaultProvider();\n const providerId = spec.provider ?? fallback.id;\n const modelId = spec.modelId ?? fallback.modelId;\n\n const builtin = getBuiltinModel(providerId, modelId);\n if (builtin) return { aiModel: builtin, custom: false };\n return { aiModel: buildCustomModel(providerId, modelId), custom: true };\n}\n\n// ─── 会话解析 ─────────────────────────────────────────────────────\n\nexport interface SessionChoice {\n sessionKey: string;\n /** 是否复用了已存在的会话(--continue / --session) */\n resumed: boolean;\n}\n\n/** 列出存储中按 updatedAt 降序的会话 key(最多 50 个) */\nexport async function listSessionsByRecency(storage: SessionStorage): Promise<string[]> {\n const keys = await storage.list();\n const entries = await Promise.all(\n keys.slice(0, 200).map(async key => {\n const s = await storage.load(key);\n return { key, updatedAt: s?.updatedAt ?? '' };\n }),\n );\n return entries\n .sort((a, b) => b.updatedAt.localeCompare(a.updatedAt))\n .map(e => e.key);\n}\n\nexport async function resolveSessionKey(\n args: Args,\n storage: SessionStorage | undefined,\n): Promise<SessionChoice> {\n if (args.noSession) return { sessionKey: `ephemeral-${Date.now().toString(36)}`, resumed: false };\n if (args.session) return { sessionKey: sanitizeKey(args.session), resumed: true };\n if (args.name) return { sessionKey: sanitizeKey(args.name), resumed: false };\n\n if (args.continue && storage) {\n const recent = await listSessionsByRecency(storage);\n if (recent.length > 0) return { sessionKey: recent[0], resumed: true };\n // 没有历史会话 → 落到新建\n }\n\n return { sessionKey: `s-${Date.now().toString(36)}`, resumed: false };\n}\n\nfunction sanitizeKey(name: string): string {\n return name.replace(/[^a-zA-Z0-9_\\-:.]/g, '_');\n}\n\n// ─── 权限策略 ─────────────────────────────────────────────────────\n\nexport interface BuildRuntimeOptions {\n args: Args;\n cwd: string;\n /** 内联人工确认回调(confirm 决策时调用;返回 true 放行) */\n confirmFn?: (req: PermissionRequest) => Promise<boolean>;\n /** 覆盖审批是否启用(默认读配置文件) */\n approvalsEnabled?: boolean;\n}\n\nexport interface BuiltRuntime {\n runtime: Runtime;\n sessionKey: string;\n storage?: SessionStorage;\n approvalManager?: ApprovalManager;\n model: ResolvedModel;\n config: AipackCliConfig;\n}\n\nconst DEFAULT_APPROVAL_CAPABILITIES = ['fs:write', 'shell:exec'];\n\nexport async function buildRuntime(options: BuildRuntimeOptions): Promise<BuiltRuntime> {\n const { args, cwd } = options;\n const config = await loadConfig(cwd);\n\n // ── 模型与 streamFn ──\n const model = resolveModel(args);\n const streamFn = createStreamFnFromAi(model.aiModel, {\n apiKey: args.apiKey,\n });\n\n // ── 工具 ──\n const tools: Tool[] = selectTools({\n tools: args.tools,\n excludeTools: args.excludeTools,\n noTools: args.noTools,\n });\n\n // ── 会话存储 ──\n const storage = args.noSession\n ? undefined\n : createFileSessionStorage({\n baseDir: args.sessionDir ?? defaultSessionDir(cwd),\n });\n const session = await resolveSessionKey(args, storage);\n\n // ── 审批与权限 ──\n const approvalsEnabled = options.approvalsEnabled ?? config.approvals?.enabled === true;\n const approvalCaps = new Set(config.approvals?.capabilities ?? DEFAULT_APPROVAL_CAPABILITIES);\n\n let approvalManager: ApprovalManager | undefined;\n if (approvalsEnabled) {\n approvalManager = createApprovalManager({\n store: new FileApprovalStore({\n baseDir: path.join(defaultConfigDir(), 'approvals'),\n }),\n });\n await approvalManager.restore();\n }\n\n const policy = buildPermissionPolicy({\n config,\n approvalCaps,\n approvalsEnabled,\n safe: args.safe === true,\n confirmFn: options.confirmFn,\n });\n\n // ── 系统提示词 ──\n const systemPrompt = buildSystemPrompt(args);\n\n // ── 组装 Runtime ──\n const runtime = await createRuntime({\n model: adaptAiModel(model.aiModel),\n streamFn,\n systemPrompt,\n tools,\n workspace: cwd,\n config: { cli: true, version: VERSION, cwd },\n sessionStorage: storage,\n thinkingLevel: args.thinking,\n permissionPolicy: policy,\n approvals: approvalManager,\n maxTurns: 50,\n compaction: { enabled: true },\n });\n\n return {\n runtime,\n sessionKey: session.sessionKey,\n storage,\n approvalManager,\n model,\n config,\n };\n}\n\nfunction buildPermissionPolicy(opts: {\n config: AipackCliConfig;\n approvalCaps: Set<string>;\n approvalsEnabled: boolean;\n safe: boolean;\n confirmFn?: (req: PermissionRequest) => Promise<boolean>;\n}): PermissionPolicy {\n const { config, approvalCaps, approvalsEnabled, safe, confirmFn } = opts;\n\n const customRules = (config.permissionRules ?? []).map(r => ({\n name: `config:${r.permission ?? r.toolName ?? '*'}`,\n toolName: r.toolName ? new RegExp(`^${r.toolName}$`) : undefined,\n permission: r.permission,\n decision: r.decision,\n }));\n\n /**\n * 高风险能力默认决策(优先级:approvals > safe > 智能默认):\n * - approvals.enabled → pending(异步审批)\n * - --safe → confirm(全部人工确认)\n * - 默认 → fs:write 放行(工作区防护兜底)、shell:exec 走 confirm,\n * 由 confirmFn 自动放行非危险命令(危险命令才弹选择器)\n */\n const highRiskRules = [...approvalCaps].flatMap(cap => {\n let decision: 'pending' | 'confirm' | 'allow';\n if (approvalsEnabled) decision = 'pending';\n else if (safe) decision = 'confirm';\n else decision = cap === 'fs:write' ? 'allow' : 'confirm';\n return [{ name: `builtin:${cap}:${decision}`, permission: cap, decision }];\n });\n\n return createPermissionPolicy({\n rules: [\n ...customRules,\n ...highRiskRules,\n { name: 'builtin:read', permission: 'fs:read', decision: 'allow' as const },\n // 未声明 permissions 的安全工具放行\n { name: 'builtin:safe-tools', decision: 'allow' as const },\n ],\n confirmFn,\n defaultDecision: 'deny',\n });\n}\n\nfunction buildSystemPrompt(args: Args): string {\n const base = args.systemPrompt ?? [\n '你是 aipack,一个终端里的 AI 编程助手。',\n '你可以使用工具读写文件、执行命令来完成用户的任务。',\n '回答保持简洁、技术化,使用与用户相同的语言。',\n ].join('\\n');\n\n const appended = args.appendSystemPrompt ?? [];\n return [base, ...appended].join('\\n\\n');\n}\n","/**\n * 初始消息组装:位置参数消息 + @file 引用 + 管道 stdin\n */\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\n\n/** 判定文件是否为图片(走 Request.media 通道) */\nconst IMAGE_EXT = new Set(['.png', '.jpg', '.jpeg', '.gif', '.webp', '.bmp']);\n\nexport interface InitialMessage {\n /** 文本消息(拼接 @文本文件 与管道内容) */\n text: string;\n /** 图片附件(base64) */\n media: string[];\n}\n\nexport async function buildInitialMessage(\n messages: string[],\n fileArgs: string[],\n stdinText: string | undefined,\n): Promise<InitialMessage> {\n const parts: string[] = [];\n const media: string[] = [];\n\n for (const file of fileArgs) {\n const abs = path.resolve(process.cwd(), file);\n const ext = path.extname(abs).toLowerCase();\n try {\n if (IMAGE_EXT.has(ext)) {\n const buf = await fs.readFile(abs);\n media.push(`data:image/${ext.slice(1)};base64,${buf.toString('base64')}`);\n } else {\n const content = await fs.readFile(abs, 'utf8');\n parts.push(`--- 文件: ${file} ---\\n${content}\\n--- 结束 ---`);\n }\n } catch (err) {\n parts.push(`[文件 ${file} 读取失败: ${err instanceof Error ? err.message : err}]`);\n }\n }\n\n if (stdinText && stdinText.trim()) {\n parts.push(`--- stdin ---\\n${stdinText.trim()}\\n--- 结束 ---`);\n }\n\n if (messages.length > 0) {\n parts.unshift(messages.join('\\n'));\n }\n\n return { text: parts.join('\\n\\n'), media };\n}\n","/**\n * print 模式(-p):非交互,处理一次提示后退出。\n * 文本回复写 stdout(可管道),工具/状态信息写 stderr。\n */\nimport type { Runtime, ResultChunk } from '@aipack-ai/agent';\nimport chalk from 'chalk';\nimport { ChunkRenderer } from './render.js';\n\nexport async function runPrintMode(\n runtime: Runtime,\n request: Parameters<Runtime['run']>[0],\n): Promise<void> {\n const renderer = new ChunkRenderer({ toolStream: process.stderr });\n let error: string | undefined;\n\n try {\n for await (const chunk of runtime.stream(request) as AsyncGenerator<ResultChunk>) {\n if (chunk.type === 'error') error = chunk.content;\n renderer.render(chunk);\n }\n } catch (err) {\n process.stderr.write(chalk.red(`错误: ${err instanceof Error ? err.message : String(err)}\\n`));\n process.exitCode = 1;\n return;\n }\n\n if (error) process.exitCode = 1;\n}\n","/**\n * 流式 chunk 的终端渲染(interactive / print 共用)\n */\nimport chalk from 'chalk';\nimport type { ResultChunk } from '@aipack-ai/agent';\n\nexport interface RenderOptions {\n /** 显示思考过程(默认折叠为省略提示) */\n showThinking?: boolean;\n /** 输出目标(默认 stdout;print 模式工具信息走 stderr 保持 stdout 纯文本) */\n toolStream?: NodeJS.WriteStream;\n}\n\nexport class ChunkRenderer {\n private thinkingShown = false;\n private inTool = false;\n\n constructor(private opts: RenderOptions = {}) {}\n\n render(chunk: ResultChunk): void {\n const err = this.opts.toolStream ?? process.stdout;\n switch (chunk.type) {\n case 'text':\n if (chunk.content) process.stdout.write(chunk.content);\n break;\n\n case 'thinking': {\n if (this.opts.showThinking && chunk.content) {\n process.stdout.write(chalk.dim(chunk.content));\n } else if (!this.thinkingShown) {\n this.thinkingShown = true;\n err.write(chalk.dim(' (思考中...)\\n'));\n }\n break;\n }\n\n case 'tool_start':\n this.inTool = true;\n err.write(chalk.cyan(`\\n⚙ ${chunk.toolName} `));\n break;\n\n case 'tool_end':\n if (this.inTool) {\n err.write(chunk.isError ? chalk.red(' ✗\\n') : chalk.green(' ✓\\n'));\n this.inTool = false;\n }\n break;\n\n case 'error':\n err.write(chalk.red(`\\n错误: ${chunk.content ?? '未知错误'}\\n`));\n break;\n\n case 'done':\n process.stdout.write('\\n');\n break;\n }\n }\n\n reset(): void {\n this.thinkingShown = false;\n this.inTool = false;\n }\n}\n","/**\n * json 模式(--mode json):全部流式事件以 JSON 行输出(stdout)。\n */\nimport type { Runtime, ResultChunk } from '@aipack-ai/agent';\n\nexport async function runJsonMode(\n runtime: Runtime,\n request: Parameters<Runtime['run']>[0],\n): Promise<void> {\n let sawError = false;\n try {\n for await (const chunk of runtime.stream(request) as AsyncGenerator<ResultChunk>) {\n if (chunk.type === 'error') sawError = true;\n const line = JSON.stringify({\n type: chunk.type,\n content: chunk.content,\n toolName: chunk.toolName,\n toolCallId: chunk.toolCallId,\n isError: chunk.isError,\n timestamp: Date.now(),\n });\n process.stdout.write(`${line}\\n`);\n }\n if (sawError) process.exitCode = 1;\n } catch (err) {\n process.stdout.write(`${JSON.stringify({\n type: 'error',\n content: err instanceof Error ? err.message : String(err),\n timestamp: Date.now(),\n })}\\n`);\n process.exitCode = 1;\n }\n}\n","/**\n * 交互模式:REPL + 斜杠命令。\n *\n * 输入非斜杠开头的行 → 发送给 runtime 流式执行;\n * 流式期间可继续输入(提示排队/丢弃),Ctrl+C 中断当前运行,连按两次退出。\n *\n * 权限确认期间关闭主 readline,由 select 选择器(方向键)接管终端,\n * 确认结束重建 readline。\n */\nimport readline from 'node:readline';\nimport chalk from 'chalk';\nimport {\n getBuiltinModels,\n adaptAiModel,\n} from '@aipack-ai/agent';\nimport type {\n Runtime,\n ResultChunk,\n Request,\n ApprovalManager,\n SessionStorage,\n ThinkingLevel,\n PermissionRequest,\n} from '@aipack-ai/agent';\nimport type { Args } from '../args.js';\nimport type { ResolvedModel } from '../builder.js';\nimport { listSessionsByRecency } from '../builder.js';\nimport { ChunkRenderer } from './render.js';\nimport { ask } from '../prompt.js';\nimport { APP_NAME, VERSION } from '../version.js';\n\nexport interface InteractiveOptions {\n runtime: Runtime;\n sessionKey: string;\n model: ResolvedModel;\n args: Args;\n storage?: SessionStorage;\n approvalManager?: ApprovalManager;\n /** 启动时的初始消息(aipack \"帮我...\") */\n initialMessages?: string[];\n /** confirm 委托(cli.ts 创建;此处包装为\"关 rl → select → 重建 rl\"后生效) */\n confirmRef?: { fn: (req: PermissionRequest) => Promise<boolean> };\n /** 基础确认逻辑(含\"总是允许\"会话记忆),由 cli.ts 注入 */\n baseConfirm: (req: PermissionRequest) => Promise<boolean>;\n}\n\nconst VALID_THINKING = new Set(['off', 'minimal', 'low', 'medium', 'high', 'max']);\n\nexport async function runInteractiveMode(opts: InteractiveOptions): Promise<void> {\n const { runtime, sessionKey, model, args, storage, approvalManager } = opts;\n\n // --resume:先选会话\n let activeKey = sessionKey;\n if (args.resume && storage) {\n const picked = await pickSessionInteractively(storage, sessionKey);\n if (picked) activeKey = picked;\n }\n\n const renderer = new ChunkRenderer();\n let busy = false;\n let sigintCount = 0;\n\n /** 主循环存活 Promise:cleanup 时 resolve,进程由 cli.ts 收尾 */\n let finish!: () => void;\n const finished = new Promise<void>(resolve => { finish = resolve; });\n\n function cleanup(): void {\n finish();\n }\n\n // ── readline 生命周期(确认期间销毁重建,避免与 select 抢占 stdin)──\n\n let rl!: readline.Interface;\n /** rl.close() 来自\"确认前接管\"而非退出 */\n let recreating = false;\n\n function setupRl(): void {\n rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n prompt: chalk.blue('aipack> '),\n });\n\n rl.on('SIGINT', () => {\n if (busy) {\n console.log(chalk.yellow('\\n中断当前运行...'));\n runtime.abort(activeKey);\n return;\n }\n sigintCount++;\n if (sigintCount >= 2) {\n console.log(chalk.dim('\\n再见'));\n rl.close();\n } else {\n console.log(chalk.dim('(再按一次 Ctrl+C 退出)'));\n rl.prompt();\n setTimeout(() => { sigintCount = 0; }, 1500);\n }\n });\n\n rl.on('close', () => {\n if (!recreating) cleanup();\n });\n\n rl.on('line', onLine);\n rl.prompt();\n }\n\n // ── 请求执行 ──\n async function send(text: string): Promise<void> {\n if (!text.trim()) return;\n busy = true;\n sigintCount = 0;\n renderer.reset();\n\n const request: Request = {\n message: text,\n type: 'message',\n channel: 'cli',\n sessionKey: activeKey,\n ephemeral: args.noSession,\n };\n\n try {\n for await (const chunk of runtime.stream(request) as AsyncGenerator<ResultChunk>) {\n renderer.render(chunk);\n }\n } catch (err) {\n console.log(chalk.red(`错误: ${err instanceof Error ? err.message : String(err)}`));\n } finally {\n busy = false;\n rl.prompt();\n }\n }\n\n // ── 斜杠命令 ──\n async function handleCommand(line: string): Promise<void> {\n const spaceIdx = line.indexOf(' ');\n const cmd = (spaceIdx === -1 ? line : line.slice(0, spaceIdx)).toLowerCase();\n const rest = spaceIdx === -1 ? '' : line.slice(spaceIdx + 1).trim();\n\n switch (cmd) {\n case '/help':\n printSlashHelp();\n break;\n\n case '/quit':\n case '/exit':\n rl.close();\n return;\n\n case '/model': {\n if (!rest) {\n console.log(chalk.dim(`当前模型: ${model.aiModel.provider}/${model.aiModel.id}`));\n console.log(chalk.dim('用法: /model provider/model-id(如 /model deepseek/deepseek-chat)'));\n break;\n }\n const slash = rest.indexOf('/');\n const provider = slash === -1 ? model.aiModel.provider : rest.slice(0, slash);\n const id = slash === -1 ? rest : rest.slice(slash + 1);\n const found = getBuiltinModels(provider).find(m => m.id === id);\n if (!found) {\n console.log(chalk.yellow(`未找到内置模型 ${provider}/${id},可用:`));\n console.log(getBuiltinModels(provider).map(m => ` ${m.id}`).join('\\n') || ' (无)');\n break;\n }\n runtime.setModel(adaptAiModel(found));\n model.aiModel = found;\n model.custom = false;\n console.log(chalk.green(`已切换到 ${provider}/${id}`));\n break;\n }\n\n case '/thinking': {\n if (!VALID_THINKING.has(rest)) {\n console.log(chalk.dim('用法: /thinking <off|minimal|low|medium|high|max>'));\n break;\n }\n runtime.setThinkingLevel(rest as ThinkingLevel);\n console.log(chalk.green(`思考级别: ${rest}`));\n break;\n }\n\n case '/system': {\n if (!rest) {\n console.log(chalk.dim('用法: /system <新的系统提示词>'));\n break;\n }\n runtime.setSystemPrompt(rest);\n console.log(chalk.green('系统提示词已更新'));\n break;\n }\n\n case '/session':\n console.log(`会话 key: ${chalk.cyan(activeKey)}`);\n console.log(`消息数: ${runtime.getMessages(activeKey).length}`);\n console.log(`持久化: ${args.noSession ? chalk.yellow('否(--no-session)') : chalk.green(storage ? '是' : '否(无存储)')}`);\n break;\n\n case '/sessions': {\n if (!storage) {\n console.log(chalk.yellow('当前为临时会话,无持久化存储'));\n break;\n }\n const sessions = await listSessionsByRecency(storage);\n if (sessions.length === 0) {\n console.log(chalk.dim('(无历史会话)'));\n break;\n }\n console.log(sessions.slice(0, 10).map((s, i) => `${s === activeKey ? chalk.green('▸ ') : ' '}${i + 1}. ${s}`).join('\\n'));\n console.log(chalk.dim('切换: 退出后用 aipack --session <key> 恢复'));\n break;\n }\n\n case '/clear':\n runtime.clearSession(activeKey);\n console.log(chalk.green('会话已清空(仅内存)'));\n break;\n\n case '/tools':\n console.log(chalk.dim('内置工具通过 --tools/--exclude-tools 配置;当前运行时未提供列举接口'));\n break;\n\n case '/approvals': {\n if (!approvalManager) {\n console.log(chalk.yellow('审批未启用(在 aipack.config.js 中配置 approvals.enabled: true)'));\n break;\n }\n const pending = approvalManager.list();\n if (pending.length === 0) {\n console.log(chalk.dim('(无未决审批)'));\n break;\n }\n for (const p of pending) {\n console.log(`${chalk.cyan(p.id)} ${p.request.toolName} ${chalk.dim(new Date(p.createdAt).toLocaleString())}${p.restored ? chalk.yellow(' (孤儿)') : ''}`);\n }\n break;\n }\n\n case '/approve':\n case '/deny': {\n if (!approvalManager) {\n console.log(chalk.yellow('审批未启用'));\n break;\n }\n if (!rest) {\n console.log(chalk.dim(`用法: ${cmd} <审批单 id>`));\n break;\n }\n const ok = approvalManager.resolve(rest, cmd === '/approve');\n console.log(ok ? chalk.green('已生效') : chalk.yellow('审批单不存在或已结算'));\n break;\n }\n\n default:\n console.log(chalk.yellow(`未知命令: ${cmd}(/help 查看全部)`));\n }\n }\n\n function printSlashHelp(): void {\n console.log(`${chalk.bold('命令:')}\n /model [provider/id] 切换模型(无参显示当前)\n /thinking <级别> off/minimal/low/medium/high/max\n /system <文本> 替换系统提示词\n /session 当前会话信息\n /sessions 列出历史会话\n /clear 清空当前会话(仅内存)\n /approvals 未决审批单\n /approve <id> 批准\n /deny <id> 驳回\n /quit 退出(Ctrl+C 双击)`);\n }\n\n // ── 行输入分发 ──\n async function onLine(line: string): Promise<void> {\n const text = line.trim();\n if (!text) {\n rl.prompt();\n return;\n }\n if (busy) {\n console.log(chalk.dim('(运行中,输入被忽略;Ctrl+C 中断)'));\n rl.prompt();\n return;\n }\n if (text.startsWith('/')) {\n await handleCommand(text);\n rl.prompt();\n return;\n }\n await send(text);\n }\n\n // ── 权限确认:关 rl → select 接管 → 重建 rl ──\n if (opts.confirmRef) {\n opts.confirmRef.fn = async (req: PermissionRequest): Promise<boolean> => {\n recreating = true;\n rl.close();\n try {\n return await opts.baseConfirm(req);\n } finally {\n recreating = false;\n setupRl();\n }\n };\n }\n\n // ── 启动横幅 ──\n const modelLabel = `${model.aiModel.provider}/${model.aiModel.id}${model.custom ? chalk.yellow(' (自定义)') : ''}`;\n console.log(chalk.bold(`${APP_NAME} ${VERSION}`) + chalk.dim(` 会话: ${activeKey}${args.noSession ? ' (临时)' : ''}`));\n console.log(chalk.dim(`模型: ${modelLabel}`));\n console.log(chalk.dim('输入 /help 查看命令,Ctrl+C 中断运行,连按两次退出\\n'));\n\n setupRl();\n\n // ── 初始消息 ──\n if (opts.initialMessages && opts.initialMessages.length > 0) {\n await send(opts.initialMessages.join('\\n'));\n }\n\n // 保持存活直至用户退出(rl close → cleanup → resolve)\n await finished;\n}\n\n/** --resume 的会话选择器 */\nexport async function pickSessionInteractively(\n storage: SessionStorage,\n currentKey: string,\n): Promise<string | undefined> {\n const sessions = await listSessionsByRecency(storage);\n if (sessions.length === 0) {\n console.log(chalk.dim('(无历史会话,将新建)'));\n return undefined;\n }\n console.log(chalk.bold('选择会话:'));\n sessions.slice(0, 15).forEach((s, i) => {\n console.log(`${s === currentKey ? chalk.green('▸ ') : ' '}${i + 1}. ${s}`);\n });\n console.log(chalk.dim(' n. 新会话'));\n const answer = await ask('编号: ');\n if (answer === '' || answer.toLowerCase() === 'n') return undefined;\n const idx = Number.parseInt(answer, 10);\n if (Number.isInteger(idx) && idx >= 1 && idx <= Math.min(sessions.length, 15)) {\n return sessions[idx - 1];\n }\n return undefined;\n}\n","/**\n * 终端交互辅助:问题 / 确认\n */\nimport readline from 'node:readline';\n\nexport function ask(question: string): Promise<string> {\n return new Promise(resolve => {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n rl.question(question, answer => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\n/** y/N 确认;非 TTY 环境直接拒绝(保守) */\nexport async function confirm(question: string): Promise<boolean> {\n if (!process.stdin.isTTY) return false;\n const answer = await ask(`${question} [y/N] `);\n return answer === 'y' || answer === 'Y' || answer === 'yes';\n}\n\n/** 读取可读流全部内容(管道 stdin) */\nexport function readStreamAll(stream: NodeJS.ReadableStream): Promise<string> {\n return new Promise(resolve => {\n let data = '';\n stream.setEncoding?.('utf8');\n stream.on('data', chunk => { data += chunk; });\n stream.on('end', () => resolve(data));\n stream.on('error', () => resolve(data));\n });\n}\n","/**\n * 原生终端选择器(无第三方依赖)\n *\n * 渲染:\n * ? 问题文本\n * ❯ 选项一\n * 选项二\n *\n * 按键:↑/↓ 或 j/k 移动,1-9 直选,回车确认,Esc/q/Ctrl+C 取消。\n * 仅在 TTY 下可用;结束时恢复 raw mode 原状并清掉选项区、保留结果摘要。\n */\nimport chalk from 'chalk';\n\nexport interface SelectOption<T extends string = string> {\n label: string;\n value: T;\n}\n\nexport async function select<T extends string = string>(\n question: string,\n options: SelectOption<T>[],\n defaultIndex = 0,\n): Promise<T | null> {\n const stdin = process.stdin;\n const out = process.stdout;\n if (!stdin.isTTY || options.length === 0) return null;\n\n return new Promise<T | null>(resolve => {\n let selected = Math.min(Math.max(defaultIndex, 0), options.length - 1);\n\n const prevRaw = stdin.isRaw ?? false;\n stdin.setRawMode(true);\n stdin.setEncoding('utf8');\n stdin.resume();\n\n /** 光标约定:每次 render 前光标位于选项区首行行首 */\n function render(): void {\n for (let i = 0; i < options.length; i++) {\n const opt = options[i];\n const line = i === selected\n ? `${chalk.cyan('❯ ')}${chalk.bold(opt.label)}`\n : ` ${opt.label}`;\n out.write(`\\x1b[2K\\r${line}\\n`);\n }\n out.write(`\\x1b[${options.length}A`);\n }\n\n function finish(value: T | null): void {\n stdin.removeListener('data', onData);\n try { stdin.setRawMode(prevRaw); } catch { /* 进程退出竞态可忽略 */ }\n if (!prevRaw) stdin.pause();\n\n // 清除选项区,写一行结果摘要\n for (let i = 0; i < options.length; i++) out.write('\\x1b[2K\\r\\n');\n out.write(`\\x1b[${options.length}A`);\n const chosen = options.find(o => o.value === value);\n const summary = chosen\n ? chalk.green(`✓ ${chosen.label}`)\n : chalk.dim('已取消');\n out.write(`\\x1b[2K\\r ${summary}\\n`);\n\n resolve(value);\n }\n\n function onData(chunk: string): void {\n if (chunk.startsWith('\\x1b[A') || chunk === 'k') {\n selected = (selected - 1 + options.length) % options.length;\n } else if (chunk.startsWith('\\x1b[B') || chunk === 'j') {\n selected = (selected + 1) % options.length;\n } else if (chunk === '\\r' || chunk === '\\n') {\n finish(options[selected].value);\n return;\n } else if (chunk === '\\x1b' || chunk === '\\x1b\\x1b' || chunk === 'q' || chunk === '\\x03') {\n finish(null);\n return;\n } else if (/^[1-9]$/.test(chunk)) {\n const idx = Number(chunk) - 1;\n if (idx < options.length) {\n finish(options[idx].value);\n return;\n }\n return;\n } else {\n return; // 其余按键无操作(不重绘)\n }\n render();\n }\n\n out.write(`${chalk.yellow('?')} ${chalk.bold(question)}\\n`);\n render();\n stdin.on('data', onData);\n });\n}\n","/**\n * 终端交互式选择器 + 工具权限确认\n *\n * 替代 y/N 输入式确认:↑/↓(或 j/k)选择,回车确认,Esc/q/Ctrl+C 取消。\n * 数字键 1-9 直选。非 TTY 环境返回取消(保守拒绝)。\n */\nimport chalk from 'chalk';\nimport type { PermissionRequest } from '@aipack-ai/agent';\nimport { select } from './select.js';\n\nexport { select };\nexport type { SelectOption } from './select.js';\n\n// ─── 危险命令检测(bash 工具)────────────────────────────────────\n\n/** [模式, 说明]:命中的 shell 命令即使默认放行模式也需人工确认 */\nconst DANGEROUS_PATTERNS: Array<[RegExp, string]> = [\n // 递归删除根/家目录(rm -rf /、rm -rf ~、rm -rf /* 等;正常子目录不受影响)\n [/rm\\s+[^;|&]*[rf][^;|&]*\\s+(\\/|~|\\$HOME)(\\/?\\*|\\s|$)/, '递归删除根/家目录'],\n [/\\bsudo(\\s|$)/, '提权执行'],\n [/\\bmkfs(\\s|\\.)/, '格式化磁盘'],\n [/\\bdd\\s+[^;|]*of=\\/dev\\//, '写入磁盘设备'],\n [/>\\s*\\/dev\\/(sd|disk|nvme)/, '覆写磁盘设备'],\n [/(curl|wget)[^|;]*\\|\\s*(sudo\\s+)?(ba|z)?sh/, '管道执行远程脚本'],\n [/chmod\\s+-R\\s+777\\s+\\/(\\s|$)/, '根目录开放全部权限'],\n [/\\b(shutdown|reboot|halt|poweroff)\\b/, '关机/重启'],\n [/:\\s*\\(\\)\\s*\\{[^}]*\\}\\s*;\\s*:/, 'fork 炸弹'],\n];\n\n/** 返回危险原因;非危险命令返回 null */\nexport function isDangerousCommand(command: string): string | null {\n for (const [pattern, reason] of DANGEROUS_PATTERNS) {\n if (pattern.test(command)) return reason;\n }\n return null;\n}\n\n// ─── 工具权限确认(三选项 + 会话级记忆)──────────────────────────\n\nexport type ToolConfirmChoice = 'once' | 'always' | 'deny';\n\n/** 从工具参数提取简短摘要(bash 显示命令,文件工具显示路径) */\nfunction summarizeArgs(req: PermissionRequest): string {\n const args = req.args as Record<string, unknown> | undefined;\n if (!args || typeof args !== 'object') return '';\n const cmd = args.command;\n if (typeof cmd === 'string') return cmd.length > 60 ? `${cmd.slice(0, 60)}…` : cmd;\n const file = args.file ?? args.path;\n if (typeof file === 'string') return file;\n return '';\n}\n\nexport interface ToolConfirmHandlerOptions {\n /**\n * 自动放行低风险操作(默认 true):\n * - bash 的非危险命令静默放行,仅危险命令弹选择器\n * - false(--safe)时全部弹选择器\n */\n autoApproveSafe?: boolean;\n}\n\nexport function createToolConfirmHandler(\n options: ToolConfirmHandlerOptions = {},\n): (req: PermissionRequest) => Promise<boolean> {\n const autoApproveSafe = options.autoApproveSafe ?? true;\n /** 会话级\"总是允许\"记忆:key = 能力组合或工具名 */\n const alwaysAllowed = new Set<string>();\n\n return async (req: PermissionRequest): Promise<boolean> => {\n if (!process.stdin.isTTY) return false;\n\n const key = req.permissions.length > 0\n ? [...req.permissions].sort().join(',')\n : `tool:${req.toolName}`;\n if (alwaysAllowed.has(key)) return true;\n\n const args = req.args as Record<string, unknown> | undefined;\n const command = typeof args?.command === 'string' ? args.command : '';\n\n // 默认模式:bash 非危险命令自动放行(不打断用户)\n if (autoApproveSafe && command && !isDangerousCommand(command)) {\n return true;\n }\n\n const dangerReason = command ? isDangerousCommand(command) : null;\n const summary = command || summarizeArgs(req);\n const question = dangerReason\n ? `危险命令(${dangerReason}):${summary}`\n : summary\n ? `允许执行 ${req.toolName}:${summary}`\n : `允许执行 ${req.toolName}`;\n\n const choice = await select<ToolConfirmChoice>(question, [\n { label: '允许', value: 'once' },\n { label: '总是允许(本会话)', value: 'always' },\n { label: '拒绝', value: 'deny' },\n ]);\n\n if (choice === 'always') {\n alwaysAllowed.add(key);\n return true;\n }\n return choice === 'once';\n };\n}\n","/**\n * aipack CLI 主逻辑:子命令分发 + 模式路由\n * 可执行入口见 src/bin.ts(bin: dist/bin.js)\n */\nimport chalk from 'chalk';\nimport type { PermissionRequest } from '@aipack-ai/agent';\nimport { handleApprovalsCommand } from './commands/approvals.js';\nimport { listModels } from './commands/models.js';\nimport { parseArgs, printHelp } from './args.js';\nimport { buildRuntime } from './builder.js';\nimport { buildInitialMessage } from './initial-message.js';\nimport { runPrintMode } from './modes/print.js';\nimport { runJsonMode } from './modes/json.js';\nimport { runInteractiveMode } from './modes/interactive.js';\nimport { readStreamAll } from './prompt.js';\nimport { createToolConfirmHandler } from './confirm.js';\nimport { createRequest } from '@aipack-ai/agent';\nimport { VERSION } from './version.js';\n\nexport async function main(argv: string[]): Promise<number> {\n // ── 子命令:approvals ──\n if (argv[0] === 'approvals' || argv[0] === 'approval') {\n return handleApprovalsCommand(argv.slice(1));\n }\n\n // ── 参数解析 ──\n const args = parseArgs(argv);\n\n if (args.help) {\n printHelp();\n return 0;\n }\n if (args.version) {\n console.log(VERSION);\n return 0;\n }\n\n const errors = args.diagnostics.filter(d => d.type === 'error');\n if (errors.length > 0) {\n for (const e of errors) console.error(chalk.red(e.message));\n printHelp();\n return 1;\n }\n for (const w of args.diagnostics.filter(d => d.type === 'warning')) {\n console.error(chalk.yellow(w.message));\n }\n\n // ── --list-models ──\n if (args.listModels !== undefined) {\n return listModels(args.listModels);\n }\n\n // ── 管道 stdin(print / json 模式)──\n let stdinText: string | undefined;\n if ((args.print || args.mode === 'json') && !process.stdin.isTTY) {\n stdinText = await readStreamAll(process.stdin);\n }\n\n // ── 初始消息 ──\n const initial = await buildInitialMessage(args.messages, args.fileArgs, stdinText);\n\n const isNonInteractive = args.print || args.mode === 'json';\n if (isNonInteractive && !initial.text.trim() && initial.media.length === 0) {\n console.error(chalk.red('非交互模式需要提供消息(位置参数、@文件或管道 stdin)'));\n return 1;\n }\n\n // ── confirm 委托:选择式确认(方向键),交互模式接管后包装 rl 重建 ──\n // 默认自动放行非危险命令;--safe 时全部人工确认\n const toolConfirm = createToolConfirmHandler({ autoApproveSafe: !args.safe });\n const confirmRef: { fn: (req: PermissionRequest) => Promise<boolean> } = {\n fn: req => toolConfirm(req),\n };\n\n // ── 构建 Runtime ──\n let built;\n try {\n built = await buildRuntime({\n args,\n cwd: process.cwd(),\n confirmFn: req => confirmRef.fn(req),\n });\n } catch (err) {\n console.error(chalk.red(`初始化失败: ${err instanceof Error ? err.message : String(err)}`));\n return 1;\n }\n\n // ── 模式分发 ──\n try {\n if (args.mode === 'json') {\n const request = createRequest(initial.text || '(空)', {\n channel: 'cli',\n sessionKey: built.sessionKey,\n ephemeral: args.noSession,\n media: initial.media,\n });\n await runJsonMode(built.runtime, request);\n } else if (args.print) {\n const request = createRequest(initial.text || '(空)', {\n channel: 'cli',\n sessionKey: built.sessionKey,\n ephemeral: args.noSession,\n media: initial.media,\n });\n await runPrintMode(built.runtime, request);\n } else {\n await runInteractiveMode({\n runtime: built.runtime,\n sessionKey: built.sessionKey,\n model: built.model,\n args,\n storage: built.storage,\n approvalManager: built.approvalManager,\n initialMessages: args.messages.length > 0 ? [initial.text] : [],\n confirmRef,\n baseConfirm: toolConfirm,\n });\n }\n } finally {\n built.approvalManager?.close();\n await built.runtime.close();\n }\n\n return process.exitCode === 1 ? 1 : 0;\n}\n","/**\n * approvals 子命令:跨进程查看/结算审批单(基于 FileApprovalStore)。\n *\n * 语义:审批单由启用 approvals 的运行进程创建(pending 时落盘)。\n * 本命令直接经 store 结算文件(同进程内存等待方无法被唤醒——跨进程审批\n * 面板场景;交互会话内请用 /approve、/deny)。\n */\nimport path from 'node:path';\nimport chalk from 'chalk';\nimport { FileApprovalStore, createApprovalManager } from '@aipack-ai/agent';\nimport type { StoredApproval } from '@aipack-ai/agent';\nimport { defaultConfigDir } from '../version.js';\n\nfunction createStore(): FileApprovalStore {\n return new FileApprovalStore({\n baseDir: path.join(defaultConfigDir(), 'approvals'),\n });\n}\n\nexport async function handleApprovalsCommand(args: string[]): Promise<number> {\n const [sub, ...rest] = args;\n\n if (!sub || sub === 'help' || sub === '--help') {\n printUsage();\n return 0;\n }\n\n const store = createStore();\n\n if (sub === 'list') {\n const pending = await store.load();\n if (pending.length === 0) {\n console.log(chalk.dim('(无未决审批单)'));\n return 0;\n }\n for (const p of pending) {\n printApproval(p);\n }\n return 0;\n }\n\n if (sub === 'approve' || sub === 'deny') {\n const id = rest[0];\n if (!id) {\n console.error(chalk.red(`用法: aipack approvals ${sub} <id>`));\n return 1;\n }\n // 经 ApprovalManager 走 restore + resolve,复用统一结算/审计路径\n const manager = createApprovalManager({ store });\n await manager.restore();\n const ok = manager.resolve(id, sub === 'approve');\n manager.close();\n if (!ok) {\n console.error(chalk.yellow(`审批单 ${id} 不存在或已结算`));\n return 1;\n }\n console.log(chalk.green(`已${sub === 'approve' ? '批准' : '驳回'} ${id}`));\n return 0;\n }\n\n printUsage();\n console.error(chalk.red(`未知子命令: ${sub}`));\n return 1;\n}\n\nfunction printApproval(p: StoredApproval): void {\n const created = new Date(p.createdAt).toLocaleString();\n const expires = p.expiresAt ? chalk.dim(` 过期 ${new Date(p.expiresAt).toLocaleTimeString()}`) : '';\n console.log(`${chalk.cyan(p.id)} ${chalk.bold(p.toolName)} ${chalk.dim(created)}${expires}`);\n if (p.permissions.length > 0) {\n console.log(chalk.dim(` 能力: ${p.permissions.join(', ')}`));\n }\n const argsStr = JSON.stringify(p.args);\n if (argsStr && argsStr !== '{}') {\n console.log(chalk.dim(` 参数: ${argsStr.length > 120 ? `${argsStr.slice(0, 120)}…` : argsStr}`));\n }\n}\n\nfunction printUsage(): void {\n console.log(`用法:\n aipack approvals list 列出未决审批单\n aipack approvals approve <id> 批准\n aipack approvals deny <id> 驳回`);\n}\n","/**\n * --list-models:列出内置目录模型(可搜索),标注 API Key 配置状态。\n */\nimport chalk from 'chalk';\nimport { getBuiltinProviders, getBuiltinModels, hasProviderConfigured } from '@aipack-ai/agent';\n\nexport function listModels(search?: string | true): number {\n const term = typeof search === 'string' ? search.toLowerCase() : undefined;\n let total = 0;\n\n for (const provider of getBuiltinProviders()) {\n const models = getBuiltinModels(provider.id);\n const matched = term\n ? models.filter(m =>\n m.id.toLowerCase().includes(term) ||\n m.name.toLowerCase().includes(term) ||\n provider.id.includes(term))\n : models;\n if (matched.length === 0) continue;\n\n const configured = hasProviderConfigured(provider.id);\n const badge = configured ? chalk.green('✓') : chalk.dim('·');\n console.log(`${badge} ${chalk.bold(provider.name)} ${chalk.dim(`(${provider.id})`)}`);\n\n for (const m of matched) {\n const flags = [\n m.reasoning ? chalk.dim('推理') : null,\n `${(m.contextWindow / 1000) | 0}k`,\n ].filter(Boolean).join(' ');\n console.log(` ${m.id.padEnd(44)} ${chalk.dim(flags)}`);\n total++;\n }\n }\n\n console.log(chalk.dim(`\\n共 ${total} 个模型。✓ = 已配置 API Key(${getEnvHint()})`));\n return 0;\n}\n\nfunction getEnvHint(): string {\n const provider = getBuiltinProviders().find(p => hasProviderConfigured(p.id));\n return provider ? `${provider.envVar} 已设置` : '未检测到任何 API Key';\n}\n"],"mappings":"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","names":["path","fs","path","path","fs","fs","path","chalk","chalk","readline","chalk","getBuiltinModels","adaptAiModel","readline","chalk","getBuiltinModels","adaptAiModel","chalk","chalk","path","chalk","FileApprovalStore","createApprovalManager","FileApprovalStore","path","chalk","createApprovalManager","chalk","getBuiltinProviders","getBuiltinModels","hasProviderConfigured","chalk"]}