codemate-ai 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -7
- package/dist/cli.js +277 -83
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -69,19 +69,18 @@ Base URL: https://api.deepseek.com
|
|
|
69
69
|
试试:codemate "创建一个 Hello World 程序"
|
|
70
70
|
```
|
|
71
71
|
|
|
72
|
-
###
|
|
72
|
+
### 基础使用
|
|
73
73
|
|
|
74
74
|
```bash
|
|
75
|
-
#
|
|
76
|
-
codemate "create a REST API with Express and TypeScript"
|
|
77
|
-
|
|
78
|
-
# Interactive mode
|
|
75
|
+
# 启动交互式模式
|
|
79
76
|
codemate
|
|
80
77
|
|
|
81
|
-
#
|
|
82
|
-
|
|
78
|
+
# 在交互界面中输入你的需求
|
|
79
|
+
> 创建一个 Express API 服务器
|
|
83
80
|
```
|
|
84
81
|
|
|
82
|
+
**注意**:当前版本仅支持交互式模式。一次性命令模式(如 `codemate "prompt"`)将在未来版本中支持。
|
|
83
|
+
|
|
85
84
|
## 📖 Usage Examples
|
|
86
85
|
|
|
87
86
|
### Create a New Project
|
package/dist/cli.js
CHANGED
|
@@ -3,6 +3,7 @@ import * as path14 from 'path';
|
|
|
3
3
|
import path14__default from 'path';
|
|
4
4
|
import { fileURLToPath } from 'url';
|
|
5
5
|
import * as fs15 from 'fs';
|
|
6
|
+
import fs15__default from 'fs';
|
|
6
7
|
import 'dotenv/config';
|
|
7
8
|
import { Command } from 'commander';
|
|
8
9
|
import * as fs16 from 'fs/promises';
|
|
@@ -14,6 +15,7 @@ import { exec, spawn } from 'child_process';
|
|
|
14
15
|
import { promisify } from 'util';
|
|
15
16
|
import * as readline from 'readline/promises';
|
|
16
17
|
import * as os from 'os';
|
|
18
|
+
import os__default from 'os';
|
|
17
19
|
import express from 'express';
|
|
18
20
|
import { createServer } from 'http';
|
|
19
21
|
import { WebSocketServer as WebSocketServer$1, WebSocket } from 'ws';
|
|
@@ -25,6 +27,7 @@ import React2, { createContext, useState, useMemo, useEffect, useContext } from
|
|
|
25
27
|
import { render, useApp, Box, Text, Static } from 'ink';
|
|
26
28
|
import TextInput from 'ink-text-input';
|
|
27
29
|
import Spinner from 'ink-spinner';
|
|
30
|
+
import readline3 from 'readline';
|
|
28
31
|
|
|
29
32
|
var __defProp = Object.defineProperty;
|
|
30
33
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -1326,14 +1329,14 @@ var EditFileTool = class extends Tool {
|
|
|
1326
1329
|
regex: z.boolean().optional().describe("Use regex for matching")
|
|
1327
1330
|
});
|
|
1328
1331
|
async execute(input) {
|
|
1329
|
-
const { path:
|
|
1330
|
-
console.log(`\u270F\uFE0F Editing file: ${
|
|
1332
|
+
const { path: path18, oldContent, newContent, regex = false } = input;
|
|
1333
|
+
console.log(`\u270F\uFE0F Editing file: ${path18}`);
|
|
1331
1334
|
try {
|
|
1332
1335
|
if (this.container) {
|
|
1333
1336
|
const fileHistory = this.container.getFileHistory();
|
|
1334
1337
|
await fileHistory.trackFile(input.path);
|
|
1335
1338
|
}
|
|
1336
|
-
const content = await fs16.readFile(
|
|
1339
|
+
const content = await fs16.readFile(path18, "utf-8");
|
|
1337
1340
|
let newFileContent;
|
|
1338
1341
|
if (regex) {
|
|
1339
1342
|
const pattern = new RegExp(oldContent, "g");
|
|
@@ -1347,15 +1350,15 @@ var EditFileTool = class extends Tool {
|
|
|
1347
1350
|
message: "No changes made (old content not found)"
|
|
1348
1351
|
};
|
|
1349
1352
|
}
|
|
1350
|
-
await fs16.writeFile(
|
|
1353
|
+
await fs16.writeFile(path18, newFileContent, "utf-8");
|
|
1351
1354
|
console.log(`\u2705 File edited successfully`);
|
|
1352
1355
|
return {
|
|
1353
1356
|
success: true,
|
|
1354
|
-
message: `File edited: ${
|
|
1357
|
+
message: `File edited: ${path18}`,
|
|
1355
1358
|
changes: newFileContent.length - content.length
|
|
1356
1359
|
};
|
|
1357
1360
|
} catch (error) {
|
|
1358
|
-
console.error(`\u274C Failed to edit file: ${
|
|
1361
|
+
console.error(`\u274C Failed to edit file: ${path18}`, error);
|
|
1359
1362
|
if (error instanceof Error) {
|
|
1360
1363
|
throw new Error(`Failed to edit file: ${error.message}`);
|
|
1361
1364
|
}
|
|
@@ -1374,30 +1377,30 @@ var DeleteFileTool = class extends Tool {
|
|
|
1374
1377
|
recursive: z.boolean().optional().describe("Delete directory recursively")
|
|
1375
1378
|
});
|
|
1376
1379
|
async execute(input) {
|
|
1377
|
-
const { path:
|
|
1378
|
-
console.log(`\u{1F5D1}\uFE0F Deleting: ${
|
|
1380
|
+
const { path: path18, recursive = false } = input;
|
|
1381
|
+
console.log(`\u{1F5D1}\uFE0F Deleting: ${path18}`);
|
|
1379
1382
|
try {
|
|
1380
1383
|
if (this.container) {
|
|
1381
1384
|
const fileHistory = this.container.getFileHistory();
|
|
1382
1385
|
await fileHistory.trackFile(input.path);
|
|
1383
1386
|
}
|
|
1384
|
-
const stats = await fs16.stat(
|
|
1387
|
+
const stats = await fs16.stat(path18);
|
|
1385
1388
|
if (stats.isDirectory()) {
|
|
1386
1389
|
if (!recursive) {
|
|
1387
1390
|
throw new Error("Cannot delete directory without recursive flag");
|
|
1388
1391
|
}
|
|
1389
|
-
await fs16.rm(
|
|
1392
|
+
await fs16.rm(path18, { recursive: true, force: true });
|
|
1390
1393
|
} else {
|
|
1391
|
-
await fs16.unlink(
|
|
1394
|
+
await fs16.unlink(path18);
|
|
1392
1395
|
}
|
|
1393
1396
|
console.log(`\u2705 Deleted successfully`);
|
|
1394
1397
|
return {
|
|
1395
1398
|
success: true,
|
|
1396
|
-
message: `Deleted: ${
|
|
1399
|
+
message: `Deleted: ${path18}`,
|
|
1397
1400
|
type: stats.isDirectory() ? "directory" : "file"
|
|
1398
1401
|
};
|
|
1399
1402
|
} catch (error) {
|
|
1400
|
-
console.error(`\u274C Failed to delete: ${
|
|
1403
|
+
console.error(`\u274C Failed to delete: ${path18}`, error);
|
|
1401
1404
|
if (error instanceof Error) {
|
|
1402
1405
|
throw new Error(`Failed to delete: ${error.message}`);
|
|
1403
1406
|
}
|
|
@@ -2023,14 +2026,14 @@ var AskUserTool = class extends Tool {
|
|
|
2023
2026
|
defaultAnswer: z.string().optional().describe("Default answer if user presses Enter")
|
|
2024
2027
|
});
|
|
2025
2028
|
async execute(input) {
|
|
2026
|
-
const { question, defaultAnswer } = input;
|
|
2027
|
-
console.log(`\u2753 Asking user: ${
|
|
2029
|
+
const { question: question2, defaultAnswer } = input;
|
|
2030
|
+
console.log(`\u2753 Asking user: ${question2}`);
|
|
2028
2031
|
try {
|
|
2029
2032
|
const rl = readline.createInterface({
|
|
2030
2033
|
input: process.stdin,
|
|
2031
2034
|
output: process.stdout
|
|
2032
2035
|
});
|
|
2033
|
-
let prompt =
|
|
2036
|
+
let prompt = question2;
|
|
2034
2037
|
if (defaultAnswer) {
|
|
2035
2038
|
prompt += ` (default: ${defaultAnswer})`;
|
|
2036
2039
|
}
|
|
@@ -2041,7 +2044,7 @@ var AskUserTool = class extends Tool {
|
|
|
2041
2044
|
console.log(`\u2705 User answered: ${finalAnswer}`);
|
|
2042
2045
|
return {
|
|
2043
2046
|
success: true,
|
|
2044
|
-
question,
|
|
2047
|
+
question: question2,
|
|
2045
2048
|
answer: finalAnswer
|
|
2046
2049
|
};
|
|
2047
2050
|
} catch (error) {
|
|
@@ -3563,65 +3566,65 @@ function normalizeWindowsPath(input = "") {
|
|
|
3563
3566
|
var _UNC_REGEX = /^[/\\]{2}/;
|
|
3564
3567
|
var _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/;
|
|
3565
3568
|
var _DRIVE_LETTER_RE = /^[A-Za-z]:$/;
|
|
3566
|
-
var normalize = function(
|
|
3567
|
-
if (
|
|
3569
|
+
var normalize = function(path18) {
|
|
3570
|
+
if (path18.length === 0) {
|
|
3568
3571
|
return ".";
|
|
3569
3572
|
}
|
|
3570
|
-
|
|
3571
|
-
const isUNCPath =
|
|
3572
|
-
const isPathAbsolute = isAbsolute3(
|
|
3573
|
-
const trailingSeparator =
|
|
3574
|
-
|
|
3575
|
-
if (
|
|
3573
|
+
path18 = normalizeWindowsPath(path18);
|
|
3574
|
+
const isUNCPath = path18.match(_UNC_REGEX);
|
|
3575
|
+
const isPathAbsolute = isAbsolute3(path18);
|
|
3576
|
+
const trailingSeparator = path18[path18.length - 1] === "/";
|
|
3577
|
+
path18 = normalizeString(path18, !isPathAbsolute);
|
|
3578
|
+
if (path18.length === 0) {
|
|
3576
3579
|
if (isPathAbsolute) {
|
|
3577
3580
|
return "/";
|
|
3578
3581
|
}
|
|
3579
3582
|
return trailingSeparator ? "./" : ".";
|
|
3580
3583
|
}
|
|
3581
3584
|
if (trailingSeparator) {
|
|
3582
|
-
|
|
3585
|
+
path18 += "/";
|
|
3583
3586
|
}
|
|
3584
|
-
if (_DRIVE_LETTER_RE.test(
|
|
3585
|
-
|
|
3587
|
+
if (_DRIVE_LETTER_RE.test(path18)) {
|
|
3588
|
+
path18 += "/";
|
|
3586
3589
|
}
|
|
3587
3590
|
if (isUNCPath) {
|
|
3588
3591
|
if (!isPathAbsolute) {
|
|
3589
|
-
return `//./${
|
|
3592
|
+
return `//./${path18}`;
|
|
3590
3593
|
}
|
|
3591
|
-
return `//${
|
|
3594
|
+
return `//${path18}`;
|
|
3592
3595
|
}
|
|
3593
|
-
return isPathAbsolute && !isAbsolute3(
|
|
3596
|
+
return isPathAbsolute && !isAbsolute3(path18) ? `/${path18}` : path18;
|
|
3594
3597
|
};
|
|
3595
3598
|
var join10 = function(...segments) {
|
|
3596
|
-
let
|
|
3599
|
+
let path18 = "";
|
|
3597
3600
|
for (const seg of segments) {
|
|
3598
3601
|
if (!seg) {
|
|
3599
3602
|
continue;
|
|
3600
3603
|
}
|
|
3601
|
-
if (
|
|
3602
|
-
const pathTrailing =
|
|
3604
|
+
if (path18.length > 0) {
|
|
3605
|
+
const pathTrailing = path18[path18.length - 1] === "/";
|
|
3603
3606
|
const segLeading = seg[0] === "/";
|
|
3604
3607
|
const both = pathTrailing && segLeading;
|
|
3605
3608
|
if (both) {
|
|
3606
|
-
|
|
3609
|
+
path18 += seg.slice(1);
|
|
3607
3610
|
} else {
|
|
3608
|
-
|
|
3611
|
+
path18 += pathTrailing || segLeading ? seg : `/${seg}`;
|
|
3609
3612
|
}
|
|
3610
3613
|
} else {
|
|
3611
|
-
|
|
3614
|
+
path18 += seg;
|
|
3612
3615
|
}
|
|
3613
3616
|
}
|
|
3614
|
-
return normalize(
|
|
3617
|
+
return normalize(path18);
|
|
3615
3618
|
};
|
|
3616
|
-
function normalizeString(
|
|
3619
|
+
function normalizeString(path18, allowAboveRoot) {
|
|
3617
3620
|
let res = "";
|
|
3618
3621
|
let lastSegmentLength = 0;
|
|
3619
3622
|
let lastSlash = -1;
|
|
3620
3623
|
let dots = 0;
|
|
3621
3624
|
let char = null;
|
|
3622
|
-
for (let index = 0; index <=
|
|
3623
|
-
if (index <
|
|
3624
|
-
char =
|
|
3625
|
+
for (let index = 0; index <= path18.length; ++index) {
|
|
3626
|
+
if (index < path18.length) {
|
|
3627
|
+
char = path18[index];
|
|
3625
3628
|
} else if (char === "/") {
|
|
3626
3629
|
break;
|
|
3627
3630
|
} else {
|
|
@@ -3657,9 +3660,9 @@ function normalizeString(path17, allowAboveRoot) {
|
|
|
3657
3660
|
}
|
|
3658
3661
|
} else {
|
|
3659
3662
|
if (res.length > 0) {
|
|
3660
|
-
res += `/${
|
|
3663
|
+
res += `/${path18.slice(lastSlash + 1, index)}`;
|
|
3661
3664
|
} else {
|
|
3662
|
-
res =
|
|
3665
|
+
res = path18.slice(lastSlash + 1, index);
|
|
3663
3666
|
}
|
|
3664
3667
|
lastSegmentLength = index - lastSlash - 1;
|
|
3665
3668
|
}
|
|
@@ -4152,60 +4155,60 @@ var CodeLocator = class {
|
|
|
4152
4155
|
let found = null;
|
|
4153
4156
|
traverseFunction(ast, {
|
|
4154
4157
|
// 查找函数
|
|
4155
|
-
FunctionDeclaration(
|
|
4156
|
-
if (type === "function" &&
|
|
4157
|
-
const parentPath =
|
|
4158
|
+
FunctionDeclaration(path18) {
|
|
4159
|
+
if (type === "function" && path18.node.id?.name === name) {
|
|
4160
|
+
const parentPath = path18.parentPath;
|
|
4158
4161
|
const isExported = parentPath && t.isExportNamedDeclaration(parentPath.node);
|
|
4159
4162
|
found = {
|
|
4160
4163
|
type: "function",
|
|
4161
4164
|
name,
|
|
4162
|
-
location: isExported ? getLocation(parentPath.node) : getLocation(
|
|
4163
|
-
code: isExported ? parentPath.toString() :
|
|
4165
|
+
location: isExported ? getLocation(parentPath.node) : getLocation(path18.node),
|
|
4166
|
+
code: isExported ? parentPath.toString() : path18.toString()
|
|
4164
4167
|
};
|
|
4165
|
-
|
|
4168
|
+
path18.stop();
|
|
4166
4169
|
}
|
|
4167
4170
|
},
|
|
4168
4171
|
// 查找类
|
|
4169
|
-
ClassDeclaration(
|
|
4170
|
-
if (type === "class" &&
|
|
4171
|
-
const parentPath =
|
|
4172
|
+
ClassDeclaration(path18) {
|
|
4173
|
+
if (type === "class" && path18.node.id?.name === name) {
|
|
4174
|
+
const parentPath = path18.parentPath;
|
|
4172
4175
|
const isExported = parentPath && t.isExportNamedDeclaration(parentPath.node);
|
|
4173
4176
|
found = {
|
|
4174
4177
|
type: "class",
|
|
4175
4178
|
name,
|
|
4176
|
-
location: isExported ? getLocation(parentPath.node) : getLocation(
|
|
4177
|
-
code: isExported ? parentPath.toString() :
|
|
4179
|
+
location: isExported ? getLocation(parentPath.node) : getLocation(path18.node),
|
|
4180
|
+
code: isExported ? parentPath.toString() : path18.toString()
|
|
4178
4181
|
};
|
|
4179
|
-
|
|
4182
|
+
path18.stop();
|
|
4180
4183
|
}
|
|
4181
4184
|
},
|
|
4182
4185
|
// 查找方法
|
|
4183
|
-
ClassMethod(
|
|
4186
|
+
ClassMethod(path18) {
|
|
4184
4187
|
if (type === "method") {
|
|
4185
|
-
const classPath =
|
|
4188
|
+
const classPath = path18.findParent((p) => p.isClassDeclaration());
|
|
4186
4189
|
const className = classPath && t.isClassDeclaration(classPath.node) ? classPath.node.id?.name : void 0;
|
|
4187
|
-
if (className === parent && t.isIdentifier(
|
|
4190
|
+
if (className === parent && t.isIdentifier(path18.node.key) && path18.node.key.name === name) {
|
|
4188
4191
|
found = {
|
|
4189
4192
|
type: "method",
|
|
4190
4193
|
name,
|
|
4191
|
-
location: getLocation(
|
|
4192
|
-
code:
|
|
4194
|
+
location: getLocation(path18.node),
|
|
4195
|
+
code: path18.toString(),
|
|
4193
4196
|
parent: className
|
|
4194
4197
|
};
|
|
4195
|
-
|
|
4198
|
+
path18.stop();
|
|
4196
4199
|
}
|
|
4197
4200
|
}
|
|
4198
4201
|
},
|
|
4199
4202
|
// 查找变量
|
|
4200
|
-
VariableDeclarator(
|
|
4201
|
-
if (type === "variable" && t.isIdentifier(
|
|
4203
|
+
VariableDeclarator(path18) {
|
|
4204
|
+
if (type === "variable" && t.isIdentifier(path18.node.id) && path18.node.id.name === name) {
|
|
4202
4205
|
found = {
|
|
4203
4206
|
type: "variable",
|
|
4204
4207
|
name,
|
|
4205
|
-
location: getLocation(
|
|
4206
|
-
code:
|
|
4208
|
+
location: getLocation(path18.node),
|
|
4209
|
+
code: path18.toString()
|
|
4207
4210
|
};
|
|
4208
|
-
|
|
4211
|
+
path18.stop();
|
|
4209
4212
|
}
|
|
4210
4213
|
}
|
|
4211
4214
|
});
|
|
@@ -4220,15 +4223,15 @@ var CodeLocator = class {
|
|
|
4220
4223
|
listFunctions(ast) {
|
|
4221
4224
|
const functions = [];
|
|
4222
4225
|
traverseFunction(ast, {
|
|
4223
|
-
FunctionDeclaration(
|
|
4224
|
-
if (
|
|
4225
|
-
const parentPath =
|
|
4226
|
+
FunctionDeclaration(path18) {
|
|
4227
|
+
if (path18.node.id) {
|
|
4228
|
+
const parentPath = path18.parentPath;
|
|
4226
4229
|
const isExported = parentPath && t.isExportNamedDeclaration(parentPath.node);
|
|
4227
4230
|
functions.push({
|
|
4228
4231
|
type: "function",
|
|
4229
|
-
name:
|
|
4230
|
-
location: isExported ? getLocation(parentPath.node) : getLocation(
|
|
4231
|
-
code: isExported ? parentPath.toString() :
|
|
4232
|
+
name: path18.node.id.name,
|
|
4233
|
+
location: isExported ? getLocation(parentPath.node) : getLocation(path18.node),
|
|
4234
|
+
code: isExported ? parentPath.toString() : path18.toString()
|
|
4232
4235
|
});
|
|
4233
4236
|
}
|
|
4234
4237
|
}
|
|
@@ -4244,15 +4247,15 @@ var CodeLocator = class {
|
|
|
4244
4247
|
listClasses(ast) {
|
|
4245
4248
|
const classes = [];
|
|
4246
4249
|
traverseFunction(ast, {
|
|
4247
|
-
ClassDeclaration(
|
|
4248
|
-
if (
|
|
4249
|
-
const parentPath =
|
|
4250
|
+
ClassDeclaration(path18) {
|
|
4251
|
+
if (path18.node.id) {
|
|
4252
|
+
const parentPath = path18.parentPath;
|
|
4250
4253
|
const isExported = parentPath && t.isExportNamedDeclaration(parentPath.node);
|
|
4251
4254
|
classes.push({
|
|
4252
4255
|
type: "class",
|
|
4253
|
-
name:
|
|
4254
|
-
location: isExported ? getLocation(parentPath.node) : getLocation(
|
|
4255
|
-
code: isExported ? parentPath.toString() :
|
|
4256
|
+
name: path18.node.id.name,
|
|
4257
|
+
location: isExported ? getLocation(parentPath.node) : getLocation(path18.node),
|
|
4258
|
+
code: isExported ? parentPath.toString() : path18.toString()
|
|
4256
4259
|
});
|
|
4257
4260
|
}
|
|
4258
4261
|
}
|
|
@@ -5305,13 +5308,182 @@ function App({ app }) {
|
|
|
5305
5308
|
return /* @__PURE__ */ React2.createElement(AppContextProvider, { app }, /* @__PURE__ */ React2.createElement(AppContent, null));
|
|
5306
5309
|
}
|
|
5307
5310
|
|
|
5311
|
+
// src/utils/firstRun.ts
|
|
5312
|
+
init_esm_shims();
|
|
5313
|
+
function isFirstRun() {
|
|
5314
|
+
const configPath = getConfigPath();
|
|
5315
|
+
return !fs15__default.existsSync(configPath);
|
|
5316
|
+
}
|
|
5317
|
+
function getConfigPath() {
|
|
5318
|
+
const homeDir = os__default.homedir();
|
|
5319
|
+
return path14__default.join(homeDir, ".aiclirc.json");
|
|
5320
|
+
}
|
|
5321
|
+
function createDefaultConfig(apiKey, provider, model, baseURL) {
|
|
5322
|
+
const defaultModels = {
|
|
5323
|
+
openai: "gpt-4",
|
|
5324
|
+
anthropic: "claude-3-5-sonnet-20241022",
|
|
5325
|
+
deepseek: "deepseek-chat",
|
|
5326
|
+
openrouter: "anthropic/claude-3.5-sonnet",
|
|
5327
|
+
custom: "gpt-4"
|
|
5328
|
+
};
|
|
5329
|
+
const defaultBaseURLs = {
|
|
5330
|
+
openai: void 0,
|
|
5331
|
+
anthropic: void 0,
|
|
5332
|
+
deepseek: "https://api.deepseek.com",
|
|
5333
|
+
openrouter: "https://openrouter.ai/api/v1",
|
|
5334
|
+
custom: void 0
|
|
5335
|
+
};
|
|
5336
|
+
const config = {
|
|
5337
|
+
app: {
|
|
5338
|
+
name: "codemate",
|
|
5339
|
+
version: "1.0.4",
|
|
5340
|
+
logLevel: "info",
|
|
5341
|
+
workDir: process.cwd()
|
|
5342
|
+
},
|
|
5343
|
+
model: {
|
|
5344
|
+
apiKey,
|
|
5345
|
+
baseURL: baseURL || defaultBaseURLs[provider] || "https://api.openai.com/v1",
|
|
5346
|
+
model: model || defaultModels[provider] || "gpt-4",
|
|
5347
|
+
temperature: 0.7
|
|
5348
|
+
},
|
|
5349
|
+
tools: {
|
|
5350
|
+
enabled: [
|
|
5351
|
+
"read_file",
|
|
5352
|
+
"write_file",
|
|
5353
|
+
"list_files",
|
|
5354
|
+
"edit_file",
|
|
5355
|
+
"delete_file",
|
|
5356
|
+
"grep",
|
|
5357
|
+
"glob",
|
|
5358
|
+
"bash"
|
|
5359
|
+
]
|
|
5360
|
+
},
|
|
5361
|
+
ui: {
|
|
5362
|
+
theme: "dark",
|
|
5363
|
+
showTimestamp: false
|
|
5364
|
+
},
|
|
5365
|
+
performance: {
|
|
5366
|
+
compression: {
|
|
5367
|
+
enabled: true,
|
|
5368
|
+
triggerRatio: 0.7,
|
|
5369
|
+
protectThreshold: 1e4,
|
|
5370
|
+
minimumPrune: 1e3,
|
|
5371
|
+
protectedTools: ["read_file", "list_files"],
|
|
5372
|
+
protectTurns: 2
|
|
5373
|
+
}
|
|
5374
|
+
},
|
|
5375
|
+
// 保存元数据用于参考
|
|
5376
|
+
_metadata: {
|
|
5377
|
+
provider,
|
|
5378
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
5379
|
+
}
|
|
5380
|
+
};
|
|
5381
|
+
const configPath = getConfigPath();
|
|
5382
|
+
fs15__default.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
5383
|
+
}
|
|
5384
|
+
|
|
5385
|
+
// src/utils/setup.ts
|
|
5386
|
+
init_esm_shims();
|
|
5387
|
+
var PROVIDERS = {
|
|
5388
|
+
openai: {
|
|
5389
|
+
name: "OpenAI",
|
|
5390
|
+
defaultModel: "gpt-4",
|
|
5391
|
+
baseURL: void 0
|
|
5392
|
+
},
|
|
5393
|
+
anthropic: {
|
|
5394
|
+
name: "Anthropic",
|
|
5395
|
+
defaultModel: "claude-3-5-sonnet-20241022",
|
|
5396
|
+
baseURL: void 0
|
|
5397
|
+
},
|
|
5398
|
+
deepseek: {
|
|
5399
|
+
name: "DeepSeek",
|
|
5400
|
+
defaultModel: "deepseek-chat",
|
|
5401
|
+
baseURL: "https://api.deepseek.com"
|
|
5402
|
+
},
|
|
5403
|
+
openrouter: {
|
|
5404
|
+
name: "OpenRouter",
|
|
5405
|
+
defaultModel: "anthropic/claude-3.5-sonnet",
|
|
5406
|
+
baseURL: "https://openrouter.ai/api/v1"
|
|
5407
|
+
},
|
|
5408
|
+
custom: {
|
|
5409
|
+
name: "\u81EA\u5B9A\u4E49 (OpenAI \u517C\u5BB9)",
|
|
5410
|
+
defaultModel: "gpt-4",
|
|
5411
|
+
baseURL: void 0
|
|
5412
|
+
}
|
|
5413
|
+
};
|
|
5414
|
+
async function runFirstTimeSetup() {
|
|
5415
|
+
const rl = readline3.createInterface({
|
|
5416
|
+
input: process.stdin,
|
|
5417
|
+
output: process.stdout
|
|
5418
|
+
});
|
|
5419
|
+
console.log("\u8BF7\u9009\u62E9 AI \u63D0\u4F9B\u5546:");
|
|
5420
|
+
console.log(" 1. OpenAI (GPT-4, GPT-3.5)");
|
|
5421
|
+
console.log(" 2. Anthropic (Claude)");
|
|
5422
|
+
console.log(" 3. DeepSeek (\u56FD\u5185\u53EF\u7528\uFF0C\u6027\u4EF7\u6BD4\u9AD8)");
|
|
5423
|
+
console.log(" 4. OpenRouter (\u591A\u6A21\u578B\u805A\u5408)");
|
|
5424
|
+
console.log(" 5. \u81EA\u5B9A\u4E49 (OpenAI \u517C\u5BB9 API)");
|
|
5425
|
+
console.log("");
|
|
5426
|
+
const choice = await question(rl, "\u8BF7\u8F93\u5165\u9009\u9879 (1-5): ");
|
|
5427
|
+
const providerKey = getProviderKey(choice.trim());
|
|
5428
|
+
console.log("");
|
|
5429
|
+
const apiKey = await question(rl, "\u8BF7\u8F93\u5165 API Key: ");
|
|
5430
|
+
console.log("");
|
|
5431
|
+
let baseURL;
|
|
5432
|
+
if (providerKey === "custom") {
|
|
5433
|
+
baseURL = await question(rl, "\u8BF7\u8F93\u5165 API Base URL (\u4F8B\u5982: https://api.example.com/v1): ");
|
|
5434
|
+
console.log("");
|
|
5435
|
+
}
|
|
5436
|
+
const defaultModel = PROVIDERS[providerKey].defaultModel;
|
|
5437
|
+
const modelInput = await question(rl, `\u8BF7\u8F93\u5165\u6A21\u578B\u540D\u79F0 (\u76F4\u63A5\u56DE\u8F66\u4F7F\u7528\u9ED8\u8BA4: ${defaultModel}): `);
|
|
5438
|
+
const model = modelInput.trim() || defaultModel;
|
|
5439
|
+
rl.close();
|
|
5440
|
+
createDefaultConfig(apiKey.trim(), providerKey, model, baseURL || PROVIDERS[providerKey].baseURL);
|
|
5441
|
+
console.log("");
|
|
5442
|
+
console.log("\u2705 \u914D\u7F6E\u5DF2\u4FDD\u5B58\u5230: ~/.aiclirc.json");
|
|
5443
|
+
console.log("");
|
|
5444
|
+
console.log(`\u63D0\u4F9B\u5546: ${PROVIDERS[providerKey].name}`);
|
|
5445
|
+
console.log(`\u6A21\u578B: ${model}`);
|
|
5446
|
+
if (baseURL || PROVIDERS[providerKey].baseURL) {
|
|
5447
|
+
console.log(`Base URL: ${baseURL || PROVIDERS[providerKey].baseURL}`);
|
|
5448
|
+
}
|
|
5449
|
+
}
|
|
5450
|
+
function getProviderKey(choice) {
|
|
5451
|
+
switch (choice) {
|
|
5452
|
+
case "1":
|
|
5453
|
+
return "openai";
|
|
5454
|
+
case "2":
|
|
5455
|
+
return "anthropic";
|
|
5456
|
+
case "3":
|
|
5457
|
+
return "deepseek";
|
|
5458
|
+
case "4":
|
|
5459
|
+
return "openrouter";
|
|
5460
|
+
case "5":
|
|
5461
|
+
return "custom";
|
|
5462
|
+
default:
|
|
5463
|
+
return "openai";
|
|
5464
|
+
}
|
|
5465
|
+
}
|
|
5466
|
+
function question(rl, query) {
|
|
5467
|
+
return new Promise((resolve8) => {
|
|
5468
|
+
rl.question(query, resolve8);
|
|
5469
|
+
});
|
|
5470
|
+
}
|
|
5471
|
+
|
|
5308
5472
|
// src/cli.ts
|
|
5309
5473
|
var program = new Command();
|
|
5310
|
-
program.name("codemate").description("AI-powered CLI assistant").version("1.0.
|
|
5474
|
+
program.name("codemate").description("AI-powered CLI assistant").version("1.0.4");
|
|
5311
5475
|
program.command("chat", { isDefault: true }).description("Start interactive chat mode").action(async () => {
|
|
5312
5476
|
try {
|
|
5477
|
+
if (isFirstRun()) {
|
|
5478
|
+
console.log("\n\u6B22\u8FCE\u4F7F\u7528 CodeMate AI! \u{1F389}\n");
|
|
5479
|
+
console.log("\u68C0\u6D4B\u5230\u8FD9\u662F\u9996\u6B21\u8FD0\u884C\uFF0C\u9700\u8981\u8FDB\u884C\u521D\u59CB\u914D\u7F6E\u3002\n");
|
|
5480
|
+
await runFirstTimeSetup();
|
|
5481
|
+
console.log("\n\u2705 \u914D\u7F6E\u5B8C\u6210\uFF01\n");
|
|
5482
|
+
console.log("\u73B0\u5728\u542F\u52A8\u4EA4\u4E92\u5F0F\u754C\u9762...\n");
|
|
5483
|
+
}
|
|
5313
5484
|
const configService = new ConfigService();
|
|
5314
|
-
|
|
5485
|
+
const configPath = getConfigPath();
|
|
5486
|
+
await configService.load(configPath);
|
|
5315
5487
|
const app = new Application(void 0, configService);
|
|
5316
5488
|
await app.start();
|
|
5317
5489
|
const sessionService = app.getContainer().get("session");
|
|
@@ -5324,12 +5496,34 @@ program.command("chat", { isDefault: true }).description("Start interactive chat
|
|
|
5324
5496
|
process.exit(1);
|
|
5325
5497
|
}
|
|
5326
5498
|
});
|
|
5499
|
+
program.command("config").description("Configure or reconfigure CodeMate AI").action(async () => {
|
|
5500
|
+
try {
|
|
5501
|
+
console.log("\n\u{1F527} CodeMate AI \u914D\u7F6E\u5411\u5BFC\n");
|
|
5502
|
+
if (!isFirstRun()) {
|
|
5503
|
+
console.log("\u5F53\u524D\u914D\u7F6E\u6587\u4EF6: ~/.aiclirc.json");
|
|
5504
|
+
console.log("\u6B64\u64CD\u4F5C\u5C06\u8986\u76D6\u73B0\u6709\u914D\u7F6E\u3002\n");
|
|
5505
|
+
}
|
|
5506
|
+
await runFirstTimeSetup();
|
|
5507
|
+
console.log("\n\u2705 \u914D\u7F6E\u5DF2\u66F4\u65B0\uFF01\n");
|
|
5508
|
+
console.log("\u73B0\u5728\u53EF\u4EE5\u4F7F\u7528 codemate \u5F00\u59CB\u5DE5\u4F5C\u4E86\u3002\n");
|
|
5509
|
+
} catch (error) {
|
|
5510
|
+
console.error("\u274C \u914D\u7F6E\u5931\u8D25:", error);
|
|
5511
|
+
process.exit(1);
|
|
5512
|
+
}
|
|
5513
|
+
});
|
|
5327
5514
|
program.command("server").description("Start HTTP server mode").option("-p, --port <port>", "Port to listen on", "3000").action(async (options) => {
|
|
5328
5515
|
try {
|
|
5516
|
+
if (isFirstRun()) {
|
|
5517
|
+
console.log("\n\u274C \u9519\u8BEF\uFF1A\u5C1A\u672A\u914D\u7F6E CodeMate AI\n");
|
|
5518
|
+
console.log("\u8BF7\u5148\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u8FDB\u884C\u914D\u7F6E\uFF1A\n");
|
|
5519
|
+
console.log(" codemate config\n");
|
|
5520
|
+
process.exit(1);
|
|
5521
|
+
}
|
|
5329
5522
|
const configService = new ConfigService();
|
|
5330
|
-
|
|
5523
|
+
const configPath = getConfigPath();
|
|
5524
|
+
await configService.load(configPath);
|
|
5331
5525
|
const app = new Application(void 0, configService);
|
|
5332
|
-
const port = parseInt(options.port, 10);
|
|
5526
|
+
const port = Number.parseInt(options.port, 10);
|
|
5333
5527
|
await app.startServer(port);
|
|
5334
5528
|
process.on("SIGINT", async () => {
|
|
5335
5529
|
console.log("\n\n\u{1F44B} Shutting down server...");
|