@caoxupei/ai-agent-cli 1.0.0 → 1.0.2

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.
Files changed (36) hide show
  1. package/README.md +16 -23
  2. package/dist/core/types.d.ts +8 -0
  3. package/dist/core/types.d.ts.map +1 -1
  4. package/dist/entrypoints/cli.js +16 -4
  5. package/dist/entrypoints/cli.js.map +1 -1
  6. package/dist/services/ai/adapters/anthropic.d.ts.map +1 -1
  7. package/dist/services/ai/adapters/anthropic.js +6 -0
  8. package/dist/services/ai/adapters/anthropic.js.map +1 -1
  9. package/dist/services/ai/adapters/openai.d.ts.map +1 -1
  10. package/dist/services/ai/adapters/openai.js +4 -0
  11. package/dist/services/ai/adapters/openai.js.map +1 -1
  12. package/dist/ui/components/Input.d.ts +3 -21
  13. package/dist/ui/components/Input.d.ts.map +1 -1
  14. package/dist/ui/components/Input.js +115 -97
  15. package/dist/ui/components/Input.js.map +1 -1
  16. package/dist/ui/index.d.ts +1 -1
  17. package/dist/ui/index.d.ts.map +1 -1
  18. package/dist/ui/index.js +1 -1
  19. package/dist/ui/index.js.map +1 -1
  20. package/dist/utils/cursor.d.ts +114 -0
  21. package/dist/utils/cursor.d.ts.map +1 -0
  22. package/dist/utils/cursor.js +256 -0
  23. package/dist/utils/cursor.js.map +1 -0
  24. package/dist/utils/externalEditor.d.ts +28 -0
  25. package/dist/utils/externalEditor.d.ts.map +1 -0
  26. package/dist/utils/externalEditor.js +138 -0
  27. package/dist/utils/externalEditor.js.map +1 -0
  28. package/dist/utils/modelConfig.d.ts +19 -0
  29. package/dist/utils/modelConfig.d.ts.map +1 -0
  30. package/dist/utils/modelConfig.js +70 -0
  31. package/dist/utils/modelConfig.js.map +1 -0
  32. package/dist/utils/tokenCounter.d.ts +69 -0
  33. package/dist/utils/tokenCounter.d.ts.map +1 -0
  34. package/dist/utils/tokenCounter.js +128 -0
  35. package/dist/utils/tokenCounter.js.map +1 -0
  36. package/package.json +3 -2
@@ -0,0 +1,256 @@
1
+ /**
2
+ * Cursor - 文本编辑光标类
3
+ *
4
+ * 提供不可变的文本编辑操作
5
+ * 所有操作返回新的 Cursor 对象,保持原对象不变
6
+ */
7
+ /**
8
+ * Cursor 类 - 管理文本和光标位置
9
+ */
10
+ export class Cursor {
11
+ text;
12
+ offset; // 光标在字符串中的位置 (0-indexed)
13
+ constructor(text, offset = 0) {
14
+ this.text = text;
15
+ // 确保 offset 在有效范围内
16
+ this.offset = Math.max(0, Math.min(text.length, offset));
17
+ }
18
+ /**
19
+ * 获取光标所在的行和列
20
+ */
21
+ getPosition() {
22
+ const lines = this.text.split('\n');
23
+ let charCount = 0;
24
+ for (let line = 0; line < lines.length; line++) {
25
+ const lineLength = lines[line].length;
26
+ if (charCount + lineLength >= this.offset) {
27
+ // 光标在当前行
28
+ return {
29
+ line,
30
+ column: this.offset - charCount,
31
+ };
32
+ }
33
+ // +1 for the '\n' character
34
+ charCount += lineLength + 1;
35
+ }
36
+ // 如果到这里,光标在最后
37
+ return {
38
+ line: Math.max(0, lines.length - 1),
39
+ column: lines[lines.length - 1]?.length || 0,
40
+ };
41
+ }
42
+ /**
43
+ * 从位置获取 offset
44
+ */
45
+ getOffsetFromPosition(position) {
46
+ const lines = this.text.split('\n');
47
+ let offset = 0;
48
+ for (let i = 0; i < position.line && i < lines.length; i++) {
49
+ offset += lines[i].length + 1; // +1 for '\n'
50
+ }
51
+ const currentLine = lines[position.line] || '';
52
+ offset += Math.min(position.column, currentLine.length);
53
+ return Math.min(offset, this.text.length);
54
+ }
55
+ /**
56
+ * 获取所有行
57
+ */
58
+ getLines() {
59
+ return this.text.split('\n');
60
+ }
61
+ /**
62
+ * 插入文本
63
+ */
64
+ insert(str) {
65
+ const newText = this.text.slice(0, this.offset) +
66
+ str +
67
+ this.text.slice(this.offset);
68
+ return new Cursor(newText, this.offset + str.length);
69
+ }
70
+ /**
71
+ * 删除光标位置的字符 (Delete键)
72
+ */
73
+ delete() {
74
+ if (this.offset >= this.text.length) {
75
+ return this;
76
+ }
77
+ const newText = this.text.slice(0, this.offset) +
78
+ this.text.slice(this.offset + 1);
79
+ return new Cursor(newText, this.offset);
80
+ }
81
+ /**
82
+ * 删除光标前的字符 (Backspace键)
83
+ */
84
+ backspace() {
85
+ if (this.offset === 0) {
86
+ return this;
87
+ }
88
+ const newText = this.text.slice(0, this.offset - 1) +
89
+ this.text.slice(this.offset);
90
+ return new Cursor(newText, this.offset - 1);
91
+ }
92
+ /**
93
+ * 光标左移
94
+ */
95
+ left() {
96
+ return new Cursor(this.text, this.offset - 1);
97
+ }
98
+ /**
99
+ * 光标右移
100
+ */
101
+ right() {
102
+ return new Cursor(this.text, this.offset + 1);
103
+ }
104
+ /**
105
+ * 光标上移
106
+ */
107
+ up() {
108
+ const pos = this.getPosition();
109
+ if (pos.line === 0) {
110
+ // 已经在第一行,移到行首
111
+ return new Cursor(this.text, 0);
112
+ }
113
+ const newPos = {
114
+ line: pos.line - 1,
115
+ column: pos.column,
116
+ };
117
+ return new Cursor(this.text, this.getOffsetFromPosition(newPos));
118
+ }
119
+ /**
120
+ * 光标下移
121
+ */
122
+ down() {
123
+ const pos = this.getPosition();
124
+ const lines = this.getLines();
125
+ if (pos.line >= lines.length - 1) {
126
+ // 已经在最后一行,移到行尾
127
+ return new Cursor(this.text, this.text.length);
128
+ }
129
+ const newPos = {
130
+ line: pos.line + 1,
131
+ column: pos.column,
132
+ };
133
+ return new Cursor(this.text, this.getOffsetFromPosition(newPos));
134
+ }
135
+ /**
136
+ * 移到行首
137
+ */
138
+ startOfLine() {
139
+ const pos = this.getPosition();
140
+ const newPos = { line: pos.line, column: 0 };
141
+ return new Cursor(this.text, this.getOffsetFromPosition(newPos));
142
+ }
143
+ /**
144
+ * 移到行尾
145
+ */
146
+ endOfLine() {
147
+ const pos = this.getPosition();
148
+ const lines = this.getLines();
149
+ const lineLength = lines[pos.line]?.length || 0;
150
+ const newPos = { line: pos.line, column: lineLength };
151
+ return new Cursor(this.text, this.getOffsetFromPosition(newPos));
152
+ }
153
+ /**
154
+ * 删除到行首
155
+ */
156
+ deleteToLineStart() {
157
+ const lineStart = this.startOfLine();
158
+ const newText = this.text.slice(0, lineStart.offset) +
159
+ this.text.slice(this.offset);
160
+ return new Cursor(newText, lineStart.offset);
161
+ }
162
+ /**
163
+ * 删除到行尾
164
+ */
165
+ deleteToLineEnd() {
166
+ const lineEnd = this.endOfLine();
167
+ const newText = this.text.slice(0, this.offset) +
168
+ this.text.slice(lineEnd.offset);
169
+ return new Cursor(newText, this.offset);
170
+ }
171
+ /**
172
+ * 移到下一个单词
173
+ */
174
+ nextWord() {
175
+ let pos = this.offset;
176
+ // 跳过当前单词字符
177
+ while (pos < this.text.length && this.isWordChar(this.text[pos])) {
178
+ pos++;
179
+ }
180
+ // 跳过空白字符
181
+ while (pos < this.text.length && !this.isWordChar(this.text[pos])) {
182
+ pos++;
183
+ }
184
+ return new Cursor(this.text, pos);
185
+ }
186
+ /**
187
+ * 移到上一个单词
188
+ */
189
+ prevWord() {
190
+ let pos = this.offset;
191
+ // 如果前一个字符不是单词字符,先跳过
192
+ if (pos > 0 && !this.isWordChar(this.text[pos - 1])) {
193
+ pos--;
194
+ }
195
+ // 跳过空白字符
196
+ while (pos > 0 && !this.isWordChar(this.text[pos - 1])) {
197
+ pos--;
198
+ }
199
+ // 跳过单词字符到单词开头
200
+ while (pos > 0 && this.isWordChar(this.text[pos - 1])) {
201
+ pos--;
202
+ }
203
+ return new Cursor(this.text, pos);
204
+ }
205
+ /**
206
+ * 删除前一个单词
207
+ */
208
+ deleteWordBefore() {
209
+ const wordStart = this.prevWord();
210
+ const newText = this.text.slice(0, wordStart.offset) +
211
+ this.text.slice(this.offset);
212
+ return new Cursor(newText, wordStart.offset);
213
+ }
214
+ /**
215
+ * 删除后一个单词
216
+ */
217
+ deleteWordAfter() {
218
+ const wordEnd = this.nextWord();
219
+ const newText = this.text.slice(0, this.offset) +
220
+ this.text.slice(wordEnd.offset);
221
+ return new Cursor(newText, this.offset);
222
+ }
223
+ /**
224
+ * 判断字符是否是单词字符
225
+ */
226
+ isWordChar(char) {
227
+ if (!char)
228
+ return false;
229
+ return /\w/.test(char);
230
+ }
231
+ /**
232
+ * 判断是否在开头
233
+ */
234
+ isAtStart() {
235
+ return this.offset === 0;
236
+ }
237
+ /**
238
+ * 判断是否在结尾
239
+ */
240
+ isAtEnd() {
241
+ return this.offset === this.text.length;
242
+ }
243
+ /**
244
+ * 比较两个 Cursor 是否相等
245
+ */
246
+ equals(other) {
247
+ return this.text === other.text && this.offset === other.offset;
248
+ }
249
+ /**
250
+ * 清空所有文本
251
+ */
252
+ clear() {
253
+ return new Cursor('', 0);
254
+ }
255
+ }
256
+ //# sourceMappingURL=cursor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../src/utils/cursor.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH;;GAEG;AACH,MAAM,OAAO,MAAM;IACN,IAAI,CAAS;IACb,MAAM,CAAS,CAAE,yBAAyB;IAEnD,YAAY,IAAY,EAAE,SAAiB,CAAC;QACxC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,mBAAmB;QACnB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7D,CAAC;IAED;;OAEG;IACH,WAAW;QACP,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,SAAS,GAAG,CAAC,CAAC;QAElB,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC;YAC7C,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;YAEtC,IAAI,SAAS,GAAG,UAAU,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBACxC,SAAS;gBACT,OAAO;oBACH,IAAI;oBACJ,MAAM,EAAE,IAAI,CAAC,MAAM,GAAG,SAAS;iBAClC,CAAC;YACN,CAAC;YAED,4BAA4B;YAC5B,SAAS,IAAI,UAAU,GAAG,CAAC,CAAC;QAChC,CAAC;QAED,cAAc;QACd,OAAO;YACH,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;YACnC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,MAAM,IAAI,CAAC;SAC/C,CAAC;IACN,CAAC;IAED;;OAEG;IACK,qBAAqB,CAAC,QAAkB;QAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,MAAM,GAAG,CAAC,CAAC;QAEf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,IAAI,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACzD,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,cAAc;QACjD,CAAC;QAED,MAAM,WAAW,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAC/C,MAAM,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;QAExD,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC9C,CAAC;IAED;;OAEG;IACH,QAAQ;QACJ,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,GAAW;QACd,MAAM,OAAO,GACT,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC;YAC/B,GAAG;YACH,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAEjC,OAAO,IAAI,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC;IACzD,CAAC;IAED;;OAEG;IACH,MAAM;QACF,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YAClC,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,MAAM,OAAO,GACT,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC;YAC/B,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAErC,OAAO,IAAI,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5C,CAAC;IAED;;OAEG;IACH,SAAS;QACL,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,MAAM,OAAO,GACT,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;YACnC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAEjC,OAAO,IAAI,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAChD,CAAC;IAED;;OAEG;IACH,IAAI;QACA,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAClD,CAAC;IAED;;OAEG;IACH,KAAK;QACD,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAClD,CAAC;IAED;;OAEG;IACH,EAAE;QACE,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QAE/B,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACjB,cAAc;YACd,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACpC,CAAC;QAED,MAAM,MAAM,GAAa;YACrB,IAAI,EAAE,GAAG,CAAC,IAAI,GAAG,CAAC;YAClB,MAAM,EAAE,GAAG,CAAC,MAAM;SACrB,CAAC;QAEF,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC,CAAC;IACrE,CAAC;IAED;;OAEG;IACH,IAAI;QACA,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAE9B,IAAI,GAAG,CAAC,IAAI,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC/B,eAAe;YACf,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACnD,CAAC;QAED,MAAM,MAAM,GAAa;YACrB,IAAI,EAAE,GAAG,CAAC,IAAI,GAAG,CAAC;YAClB,MAAM,EAAE,GAAG,CAAC,MAAM;SACrB,CAAC;QAEF,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC,CAAC;IACrE,CAAC;IAED;;OAEG;IACH,WAAW;QACP,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAa,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;QACvD,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC,CAAC;IACrE,CAAC;IAED;;OAEG;IACH,SAAS;QACL,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC9B,MAAM,UAAU,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC;QAChD,MAAM,MAAM,GAAa,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;QAChE,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC,CAAC;IACrE,CAAC;IAED;;OAEG;IACH,iBAAiB;QACb,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QACrC,MAAM,OAAO,GACT,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC;YACpC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAEjC,OAAO,IAAI,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IACjD,CAAC;IAED;;OAEG;IACH,eAAe;QACX,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QACjC,MAAM,OAAO,GACT,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC;YAC/B,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAEpC,OAAO,IAAI,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5C,CAAC;IAED;;OAEG;IACH,QAAQ;QACJ,IAAI,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC;QAEtB,WAAW;QACX,OAAO,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YAC/D,GAAG,EAAE,CAAC;QACV,CAAC;QAED,SAAS;QACT,OAAO,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YAChE,GAAG,EAAE,CAAC;QACV,CAAC;QAED,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACtC,CAAC;IAED;;OAEG;IACH,QAAQ;QACJ,IAAI,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC;QAEtB,oBAAoB;QACpB,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAClD,GAAG,EAAE,CAAC;QACV,CAAC;QAED,SAAS;QACT,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACrD,GAAG,EAAE,CAAC;QACV,CAAC;QAED,cAAc;QACd,OAAO,GAAG,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACpD,GAAG,EAAE,CAAC;QACV,CAAC;QAED,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACtC,CAAC;IAED;;OAEG;IACH,gBAAgB;QACZ,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClC,MAAM,OAAO,GACT,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC;YACpC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAEjC,OAAO,IAAI,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IACjD,CAAC;IAED;;OAEG;IACH,eAAe;QACX,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChC,MAAM,OAAO,GACT,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC;YAC/B,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAEpC,OAAO,IAAI,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5C,CAAC;IAED;;OAEG;IACK,UAAU,CAAC,IAAwB;QACvC,IAAI,CAAC,IAAI;YAAE,OAAO,KAAK,CAAC;QACxB,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,SAAS;QACL,OAAO,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,OAAO;QACH,OAAO,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;IAC5C,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,KAAa;QAChB,OAAO,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,CAAC;IACpE,CAAC;IAED;;OAEG;IACH,KAAK;QACD,OAAO,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAC7B,CAAC;CACJ"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * 外部编辑器集成
3
+ * 支持打开外部编辑器编辑长文本
4
+ */
5
+ /**
6
+ * 编辑器结果
7
+ */
8
+ export interface EditorResult {
9
+ text: string | null;
10
+ editorLabel?: string;
11
+ error?: Error;
12
+ }
13
+ /**
14
+ * 启动外部编辑器
15
+ *
16
+ * @param initialText - 初始文本内容
17
+ * @returns 编辑后的文本和编辑器信息
18
+ */
19
+ export declare function launchExternalEditor(initialText?: string): Promise<EditorResult>;
20
+ /**
21
+ * 检查编辑器是否可用
22
+ */
23
+ export declare function isEditorAvailable(): Promise<boolean>;
24
+ /**
25
+ * 获取当前配置的编辑器名称
26
+ */
27
+ export declare function getConfiguredEditor(): Promise<string | null>;
28
+ //# sourceMappingURL=externalEditor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"externalEditor.d.ts","sourceRoot":"","sources":["../../src/utils/externalEditor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH;;GAEG;AACH,MAAM,WAAW,YAAY;IACzB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,KAAK,CAAC;CACjB;AAyDD;;;;;GAKG;AACH,wBAAsB,oBAAoB,CACtC,WAAW,GAAE,MAAW,GACzB,OAAO,CAAC,YAAY,CAAC,CAsEvB;AAED;;GAEG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC,CAG1D;AAED;;GAEG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAElE"}
@@ -0,0 +1,138 @@
1
+ /**
2
+ * 外部编辑器集成
3
+ * 支持打开外部编辑器编辑长文本
4
+ */
5
+ import { execSync, exec } from 'child_process';
6
+ import * as fs from 'fs/promises';
7
+ import * as os from 'os';
8
+ import * as path from 'path';
9
+ import { promisify } from 'util';
10
+ const execAsync = promisify(exec);
11
+ /**
12
+ * 检测系统中可用的编辑器
13
+ */
14
+ async function detectAvailableEditor() {
15
+ // 优先使用环境变量
16
+ const editorFromEnv = process.env.EDITOR || process.env.VISUAL;
17
+ if (editorFromEnv) {
18
+ return editorFromEnv;
19
+ }
20
+ // 按优先级尝试常见编辑器
21
+ const editors = process.platform === 'win32'
22
+ ? ['code', 'notepad', 'vim', 'vi']
23
+ : ['code', 'nano', 'vim', 'vi'];
24
+ for (const editor of editors) {
25
+ try {
26
+ if (process.platform === 'win32') {
27
+ // Windows: 使用 where 命令
28
+ await execAsync(`where ${editor}`, { timeout: 1000 });
29
+ }
30
+ else {
31
+ // Unix-like: 使用 which 命令
32
+ await execAsync(`which ${editor}`, { timeout: 1000 });
33
+ }
34
+ return editor;
35
+ }
36
+ catch {
37
+ // 编辑器不存在,继续下一个
38
+ continue;
39
+ }
40
+ }
41
+ return null;
42
+ }
43
+ /**
44
+ * 获取编辑器的友好名称
45
+ */
46
+ function getEditorLabel(editorPath) {
47
+ const basename = path.basename(editorPath).toLowerCase();
48
+ const labels = {
49
+ code: 'VS Code',
50
+ 'code-insiders': 'VS Code Insiders',
51
+ vim: 'Vim',
52
+ vi: 'Vi',
53
+ nano: 'Nano',
54
+ emacs: 'Emacs',
55
+ notepad: 'Notepad',
56
+ 'notepad++': 'Notepad++',
57
+ };
58
+ return labels[basename] || basename;
59
+ }
60
+ /**
61
+ * 启动外部编辑器
62
+ *
63
+ * @param initialText - 初始文本内容
64
+ * @returns 编辑后的文本和编辑器信息
65
+ */
66
+ export async function launchExternalEditor(initialText = '') {
67
+ let tmpFile = null;
68
+ try {
69
+ // 1. 检测可用编辑器
70
+ const editor = await detectAvailableEditor();
71
+ if (!editor) {
72
+ return {
73
+ text: null,
74
+ error: new Error('No editor found. Please set $EDITOR environment variable or install code/nano/vim.'),
75
+ };
76
+ }
77
+ // 2. 创建临时文件
78
+ tmpFile = path.join(os.tmpdir(), `ai-agent-${Date.now()}-${Math.random().toString(36).slice(2)}.md`);
79
+ await fs.writeFile(tmpFile, initialText, 'utf-8');
80
+ // 3. 构建编辑器命令
81
+ let command;
82
+ const editorName = path.basename(editor).toLowerCase();
83
+ if (editorName === 'code' || editorName.startsWith('code-')) {
84
+ // VS Code: 使用 --wait 等待关闭
85
+ command = `"${editor}" --wait "${tmpFile}"`;
86
+ }
87
+ else if (editorName === 'vim' || editorName === 'vi' || editorName === 'nano') {
88
+ // 终端编辑器: 直接打开
89
+ command = `"${editor}" "${tmpFile}"`;
90
+ }
91
+ else {
92
+ // 默认方式
93
+ command = `"${editor}" "${tmpFile}"`;
94
+ }
95
+ // 4. 打开编辑器(同步等待关闭)
96
+ execSync(command, {
97
+ stdio: 'inherit',
98
+ windowsHide: false,
99
+ });
100
+ // 5. 读取编辑后的内容
101
+ const editedText = await fs.readFile(tmpFile, 'utf-8');
102
+ // 6. 清理临时文件
103
+ await fs.unlink(tmpFile);
104
+ return {
105
+ text: editedText,
106
+ editorLabel: getEditorLabel(editor),
107
+ };
108
+ }
109
+ catch (error) {
110
+ // 清理临时文件
111
+ if (tmpFile) {
112
+ try {
113
+ await fs.unlink(tmpFile);
114
+ }
115
+ catch {
116
+ // 忽略清理错误
117
+ }
118
+ }
119
+ return {
120
+ text: null,
121
+ error: error,
122
+ };
123
+ }
124
+ }
125
+ /**
126
+ * 检查编辑器是否可用
127
+ */
128
+ export async function isEditorAvailable() {
129
+ const editor = await detectAvailableEditor();
130
+ return editor !== null;
131
+ }
132
+ /**
133
+ * 获取当前配置的编辑器名称
134
+ */
135
+ export async function getConfiguredEditor() {
136
+ return await detectAvailableEditor();
137
+ }
138
+ //# sourceMappingURL=externalEditor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"externalEditor.js","sourceRoot":"","sources":["../../src/utils/externalEditor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * 模型上下文长度配置
3
+ */
4
+ /**
5
+ * 获取模型的上下文长度
6
+ *
7
+ * @param provider - AI 提供商
8
+ * @param model - 模型名称
9
+ * @returns 上下文长度(token 数)
10
+ */
11
+ export declare function getModelContextLength(provider: string, model: string): number;
12
+ /**
13
+ * 获取模型的简短名称(用于显示)
14
+ *
15
+ * @param model - 完整模型名称
16
+ * @returns 简短名称
17
+ */
18
+ export declare function getModelDisplayName(model: string): string;
19
+ //# sourceMappingURL=modelConfig.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modelConfig.d.ts","sourceRoot":"","sources":["../../src/utils/modelConfig.ts"],"names":[],"mappings":"AAAA;;GAEG;AAiCH;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAW7E;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAczD"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * 模型上下文长度配置
3
+ */
4
+ // Anthropic Claude 模型
5
+ const ANTHROPIC_MODELS = {
6
+ 'claude-opus-4-20250514': 200000,
7
+ 'claude-sonnet-4-20250514': 200000,
8
+ 'claude-3.5-sonnet': 200000,
9
+ 'claude-3-opus': 200000,
10
+ 'claude-3-sonnet': 200000,
11
+ 'claude-3-haiku': 200000,
12
+ };
13
+ // OpenAI 模型
14
+ const OPENAI_MODELS = {
15
+ 'gpt-4': 128000,
16
+ 'gpt-4-turbo': 128000,
17
+ 'gpt-4-turbo-preview': 128000,
18
+ 'gpt-4-0125-preview': 128000,
19
+ 'gpt-4-1106-preview': 128000,
20
+ 'gpt-3.5-turbo': 16385,
21
+ 'gpt-3.5-turbo-16k': 16384,
22
+ 'o1-preview': 128000,
23
+ 'o1-mini': 128000,
24
+ };
25
+ // Google Gemini 模型
26
+ const GEMINI_MODELS = {
27
+ 'gemini-2.0-flash-exp': 1000000,
28
+ 'gemini-1.5-pro': 2000000,
29
+ 'gemini-1.5-flash': 1000000,
30
+ 'gemini-1.0-pro': 32000,
31
+ };
32
+ /**
33
+ * 获取模型的上下文长度
34
+ *
35
+ * @param provider - AI 提供商
36
+ * @param model - 模型名称
37
+ * @returns 上下文长度(token 数)
38
+ */
39
+ export function getModelContextLength(provider, model) {
40
+ switch (provider.toLowerCase()) {
41
+ case 'anthropic':
42
+ return ANTHROPIC_MODELS[model] || 200000; // 默认 200k
43
+ case 'openai':
44
+ return OPENAI_MODELS[model] || 128000; // 默认 128k
45
+ case 'gemini':
46
+ return GEMINI_MODELS[model] || 1000000; // 默认 1M
47
+ default:
48
+ return 200000; // 通用默认值
49
+ }
50
+ }
51
+ /**
52
+ * 获取模型的简短名称(用于显示)
53
+ *
54
+ * @param model - 完整模型名称
55
+ * @returns 简短名称
56
+ */
57
+ export function getModelDisplayName(model) {
58
+ // 移除日期后缀
59
+ const withoutDate = model.replace(/-\d{8}$/, '');
60
+ // 已知的简化映射
61
+ const displayNames = {
62
+ 'claude-opus-4': 'claude-opus-4',
63
+ 'claude-sonnet-4': 'claude-sonnet-4',
64
+ 'claude-3.5-sonnet': 'claude-3.5-sonnet',
65
+ 'gemini-2.0-flash-exp': 'gemini-2.0-flash',
66
+ 'gpt-4-turbo-preview': 'gpt-4-turbo',
67
+ };
68
+ return displayNames[withoutDate] || withoutDate;
69
+ }
70
+ //# sourceMappingURL=modelConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modelConfig.js","sourceRoot":"","sources":["../../src/utils/modelConfig.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,sBAAsB;AACtB,MAAM,gBAAgB,GAA2B;IAC7C,wBAAwB,EAAE,MAAM;IAChC,0BAA0B,EAAE,MAAM;IAClC,mBAAmB,EAAE,MAAM;IAC3B,eAAe,EAAE,MAAM;IACvB,iBAAiB,EAAE,MAAM;IACzB,gBAAgB,EAAE,MAAM;CAC3B,CAAC;AAEF,YAAY;AACZ,MAAM,aAAa,GAA2B;IAC1C,OAAO,EAAE,MAAM;IACf,aAAa,EAAE,MAAM;IACrB,qBAAqB,EAAE,MAAM;IAC7B,oBAAoB,EAAE,MAAM;IAC5B,oBAAoB,EAAE,MAAM;IAC5B,eAAe,EAAE,KAAK;IACtB,mBAAmB,EAAE,KAAK;IAC1B,YAAY,EAAE,MAAM;IACpB,SAAS,EAAE,MAAM;CACpB,CAAC;AAEF,mBAAmB;AACnB,MAAM,aAAa,GAA2B;IAC1C,sBAAsB,EAAE,OAAO;IAC/B,gBAAgB,EAAE,OAAO;IACzB,kBAAkB,EAAE,OAAO;IAC3B,gBAAgB,EAAE,KAAK;CAC1B,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAAgB,EAAE,KAAa;IACjE,QAAQ,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC;QAC7B,KAAK,WAAW;YACZ,OAAO,gBAAgB,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,CAAC,UAAU;QACxD,KAAK,QAAQ;YACT,OAAO,aAAa,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,CAAI,UAAU;QACxD,KAAK,QAAQ;YACT,OAAO,aAAa,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,CAAG,QAAQ;QACtD;YACI,OAAO,MAAM,CAAC,CAAC,QAAQ;IAC/B,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAa;IAC7C,SAAS;IACT,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IAEjD,UAAU;IACV,MAAM,YAAY,GAA2B;QACzC,eAAe,EAAE,eAAe;QAChC,iBAAiB,EAAE,iBAAiB;QACpC,mBAAmB,EAAE,mBAAmB;QACxC,sBAAsB,EAAE,kBAAkB;QAC1C,qBAAqB,EAAE,aAAa;KACvC,CAAC;IAEF,OAAO,YAAY,CAAC,WAAW,CAAC,IAAI,WAAW,CAAC;AACpD,CAAC"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Token 计数和格式化工具
3
+ * 用于估算和显示 Token 使用情况
4
+ */
5
+ import type { Message } from '../core/types.js';
6
+ /**
7
+ * 估算文本的 Token 数量
8
+ *
9
+ * 使用简单的启发式方法: ~4 字符 ≈ 1 token
10
+ * 对于中文: ~2 字符 ≈ 1 token
11
+ *
12
+ * @param text - 要计数的文本
13
+ * @returns Token 数量估算
14
+ */
15
+ export declare function estimateTokens(text: string): number;
16
+ /**
17
+ * 统计消息历史的总 Token 数
18
+ *
19
+ * @param messages - 消息历史数组
20
+ * @returns 总 Token 数估算
21
+ */
22
+ export declare function countTokens(messages: Message[]): number;
23
+ /**
24
+ * 格式化 Token 数量为人类可读的字符串
25
+ *
26
+ * @param tokens - Token 数量
27
+ * @returns 格式化后的字符串 (例: "1.5k", "245", "12.3k")
28
+ */
29
+ export declare function formatTokenCount(tokens: number): string;
30
+ /**
31
+ * 获取 Token 使用百分比
32
+ *
33
+ * @param current - 当前使用的 Token 数
34
+ * @param max - 最大 Token 数
35
+ * @returns 百分比 (0-100)
36
+ */
37
+ export declare function getTokenPercentage(current: number, max: number): number;
38
+ /**
39
+ * 判断 Token 使用是否接近限制
40
+ *
41
+ * @param current - 当前使用的 Token 数
42
+ * @param max - 最大 Token 数
43
+ * @returns 是否需要警告
44
+ */
45
+ export declare function isTokenWarning(current: number, max: number): boolean;
46
+ /**
47
+ * 判断 Token 使用是否超过限制
48
+ *
49
+ * @param current - 当前使用的 Token 数
50
+ * @param max - 最大 Token 数
51
+ * @returns 是否超限
52
+ */
53
+ export declare function isTokenDanger(current: number, max: number): boolean;
54
+ /**
55
+ * 格式化 Token 使用情况为显示字符串
56
+ *
57
+ * @param current - 当前使用的 Token 数
58
+ * @param max - 最大 Token 数
59
+ * @returns 格式化字符串 (例: "12.5k/200k (6%)")
60
+ */
61
+ export declare function formatTokenUsage(current: number, max: number): string;
62
+ /**
63
+ * 从消息历史中获取准确的 Token 数(使用 API usage数据)
64
+ *
65
+ * @param messages - 消息历史数组
66
+ * @returns Token 数(从最近的 assistant 消息的 usage 数据)
67
+ */
68
+ export declare function countTokensFromUsage(messages: Message[]): number;
69
+ //# sourceMappingURL=tokenCounter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokenCounter.d.ts","sourceRoot":"","sources":["../../src/utils/tokenCounter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAEhD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQnD;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM,CAmBvD;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAQvD;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAGvE;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAGpE;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAGnE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAGrE;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM,CAYhE"}