codemate-ai 1.0.2 → 1.0.3

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 (2) hide show
  1. package/dist/cli.js +235 -83
  2. package/package.json +1 -1
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: path17, oldContent, newContent, regex = false } = input;
1330
- console.log(`\u270F\uFE0F Editing file: ${path17}`);
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(path17, "utf-8");
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(path17, newFileContent, "utf-8");
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: ${path17}`,
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: ${path17}`, error);
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: path17, recursive = false } = input;
1378
- console.log(`\u{1F5D1}\uFE0F Deleting: ${path17}`);
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(path17);
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(path17, { recursive: true, force: true });
1392
+ await fs16.rm(path18, { recursive: true, force: true });
1390
1393
  } else {
1391
- await fs16.unlink(path17);
1394
+ await fs16.unlink(path18);
1392
1395
  }
1393
1396
  console.log(`\u2705 Deleted successfully`);
1394
1397
  return {
1395
1398
  success: true,
1396
- message: `Deleted: ${path17}`,
1399
+ message: `Deleted: ${path18}`,
1397
1400
  type: stats.isDirectory() ? "directory" : "file"
1398
1401
  };
1399
1402
  } catch (error) {
1400
- console.error(`\u274C Failed to delete: ${path17}`, error);
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: ${question}`);
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 = question;
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(path17) {
3567
- if (path17.length === 0) {
3569
+ var normalize = function(path18) {
3570
+ if (path18.length === 0) {
3568
3571
  return ".";
3569
3572
  }
3570
- path17 = normalizeWindowsPath(path17);
3571
- const isUNCPath = path17.match(_UNC_REGEX);
3572
- const isPathAbsolute = isAbsolute3(path17);
3573
- const trailingSeparator = path17[path17.length - 1] === "/";
3574
- path17 = normalizeString(path17, !isPathAbsolute);
3575
- if (path17.length === 0) {
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
- path17 += "/";
3585
+ path18 += "/";
3583
3586
  }
3584
- if (_DRIVE_LETTER_RE.test(path17)) {
3585
- path17 += "/";
3587
+ if (_DRIVE_LETTER_RE.test(path18)) {
3588
+ path18 += "/";
3586
3589
  }
3587
3590
  if (isUNCPath) {
3588
3591
  if (!isPathAbsolute) {
3589
- return `//./${path17}`;
3592
+ return `//./${path18}`;
3590
3593
  }
3591
- return `//${path17}`;
3594
+ return `//${path18}`;
3592
3595
  }
3593
- return isPathAbsolute && !isAbsolute3(path17) ? `/${path17}` : path17;
3596
+ return isPathAbsolute && !isAbsolute3(path18) ? `/${path18}` : path18;
3594
3597
  };
3595
3598
  var join10 = function(...segments) {
3596
- let path17 = "";
3599
+ let path18 = "";
3597
3600
  for (const seg of segments) {
3598
3601
  if (!seg) {
3599
3602
  continue;
3600
3603
  }
3601
- if (path17.length > 0) {
3602
- const pathTrailing = path17[path17.length - 1] === "/";
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
- path17 += seg.slice(1);
3609
+ path18 += seg.slice(1);
3607
3610
  } else {
3608
- path17 += pathTrailing || segLeading ? seg : `/${seg}`;
3611
+ path18 += pathTrailing || segLeading ? seg : `/${seg}`;
3609
3612
  }
3610
3613
  } else {
3611
- path17 += seg;
3614
+ path18 += seg;
3612
3615
  }
3613
3616
  }
3614
- return normalize(path17);
3617
+ return normalize(path18);
3615
3618
  };
3616
- function normalizeString(path17, allowAboveRoot) {
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 <= path17.length; ++index) {
3623
- if (index < path17.length) {
3624
- char = path17[index];
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 += `/${path17.slice(lastSlash + 1, index)}`;
3663
+ res += `/${path18.slice(lastSlash + 1, index)}`;
3661
3664
  } else {
3662
- res = path17.slice(lastSlash + 1, index);
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(path17) {
4156
- if (type === "function" && path17.node.id?.name === name) {
4157
- const parentPath = path17.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(path17.node),
4163
- code: isExported ? parentPath.toString() : path17.toString()
4165
+ location: isExported ? getLocation(parentPath.node) : getLocation(path18.node),
4166
+ code: isExported ? parentPath.toString() : path18.toString()
4164
4167
  };
4165
- path17.stop();
4168
+ path18.stop();
4166
4169
  }
4167
4170
  },
4168
4171
  // 查找类
4169
- ClassDeclaration(path17) {
4170
- if (type === "class" && path17.node.id?.name === name) {
4171
- const parentPath = path17.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(path17.node),
4177
- code: isExported ? parentPath.toString() : path17.toString()
4179
+ location: isExported ? getLocation(parentPath.node) : getLocation(path18.node),
4180
+ code: isExported ? parentPath.toString() : path18.toString()
4178
4181
  };
4179
- path17.stop();
4182
+ path18.stop();
4180
4183
  }
4181
4184
  },
4182
4185
  // 查找方法
4183
- ClassMethod(path17) {
4186
+ ClassMethod(path18) {
4184
4187
  if (type === "method") {
4185
- const classPath = path17.findParent((p) => p.isClassDeclaration());
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(path17.node.key) && path17.node.key.name === name) {
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(path17.node),
4192
- code: path17.toString(),
4194
+ location: getLocation(path18.node),
4195
+ code: path18.toString(),
4193
4196
  parent: className
4194
4197
  };
4195
- path17.stop();
4198
+ path18.stop();
4196
4199
  }
4197
4200
  }
4198
4201
  },
4199
4202
  // 查找变量
4200
- VariableDeclarator(path17) {
4201
- if (type === "variable" && t.isIdentifier(path17.node.id) && path17.node.id.name === name) {
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(path17.node),
4206
- code: path17.toString()
4208
+ location: getLocation(path18.node),
4209
+ code: path18.toString()
4207
4210
  };
4208
- path17.stop();
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(path17) {
4224
- if (path17.node.id) {
4225
- const parentPath = path17.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: path17.node.id.name,
4230
- location: isExported ? getLocation(parentPath.node) : getLocation(path17.node),
4231
- code: isExported ? parentPath.toString() : path17.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(path17) {
4248
- if (path17.node.id) {
4249
- const parentPath = path17.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: path17.node.id.name,
4254
- location: isExported ? getLocation(parentPath.node) : getLocation(path17.node),
4255
- code: isExported ? parentPath.toString() : path17.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,140 @@ 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 config = {
5330
+ provider,
5331
+ apiKey,
5332
+ model: model || defaultModels[provider] || "gpt-4",
5333
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
5334
+ };
5335
+ if (baseURL) {
5336
+ config.baseURL = baseURL;
5337
+ }
5338
+ const configPath = getConfigPath();
5339
+ fs15__default.writeFileSync(configPath, JSON.stringify(config, null, 2));
5340
+ }
5341
+
5342
+ // src/utils/setup.ts
5343
+ init_esm_shims();
5344
+ var PROVIDERS = {
5345
+ openai: {
5346
+ name: "OpenAI",
5347
+ defaultModel: "gpt-4",
5348
+ baseURL: void 0
5349
+ },
5350
+ anthropic: {
5351
+ name: "Anthropic",
5352
+ defaultModel: "claude-3-5-sonnet-20241022",
5353
+ baseURL: void 0
5354
+ },
5355
+ deepseek: {
5356
+ name: "DeepSeek",
5357
+ defaultModel: "deepseek-chat",
5358
+ baseURL: "https://api.deepseek.com"
5359
+ },
5360
+ openrouter: {
5361
+ name: "OpenRouter",
5362
+ defaultModel: "anthropic/claude-3.5-sonnet",
5363
+ baseURL: "https://openrouter.ai/api/v1"
5364
+ },
5365
+ custom: {
5366
+ name: "\u81EA\u5B9A\u4E49 (OpenAI \u517C\u5BB9)",
5367
+ defaultModel: "gpt-4",
5368
+ baseURL: void 0
5369
+ }
5370
+ };
5371
+ async function runFirstTimeSetup() {
5372
+ const rl = readline3.createInterface({
5373
+ input: process.stdin,
5374
+ output: process.stdout
5375
+ });
5376
+ console.log("\u8BF7\u9009\u62E9 AI \u63D0\u4F9B\u5546:");
5377
+ console.log(" 1. OpenAI (GPT-4, GPT-3.5)");
5378
+ console.log(" 2. Anthropic (Claude)");
5379
+ console.log(" 3. DeepSeek (\u56FD\u5185\u53EF\u7528\uFF0C\u6027\u4EF7\u6BD4\u9AD8)");
5380
+ console.log(" 4. OpenRouter (\u591A\u6A21\u578B\u805A\u5408)");
5381
+ console.log(" 5. \u81EA\u5B9A\u4E49 (OpenAI \u517C\u5BB9 API)");
5382
+ console.log("");
5383
+ const choice = await question(rl, "\u8BF7\u8F93\u5165\u9009\u9879 (1-5): ");
5384
+ const providerKey = getProviderKey(choice.trim());
5385
+ console.log("");
5386
+ const apiKey = await question(rl, "\u8BF7\u8F93\u5165 API Key: ");
5387
+ console.log("");
5388
+ let baseURL;
5389
+ if (providerKey === "custom") {
5390
+ baseURL = await question(rl, "\u8BF7\u8F93\u5165 API Base URL (\u4F8B\u5982: https://api.example.com/v1): ");
5391
+ console.log("");
5392
+ }
5393
+ const defaultModel = PROVIDERS[providerKey].defaultModel;
5394
+ const modelInput = await question(rl, `\u8BF7\u8F93\u5165\u6A21\u578B\u540D\u79F0 (\u76F4\u63A5\u56DE\u8F66\u4F7F\u7528\u9ED8\u8BA4: ${defaultModel}): `);
5395
+ const model = modelInput.trim() || defaultModel;
5396
+ rl.close();
5397
+ createDefaultConfig(apiKey.trim(), providerKey, model, baseURL || PROVIDERS[providerKey].baseURL);
5398
+ console.log("");
5399
+ console.log("\u2705 \u914D\u7F6E\u5DF2\u4FDD\u5B58\u5230: ~/.aiclirc.json");
5400
+ console.log("");
5401
+ console.log(`\u63D0\u4F9B\u5546: ${PROVIDERS[providerKey].name}`);
5402
+ console.log(`\u6A21\u578B: ${model}`);
5403
+ if (baseURL || PROVIDERS[providerKey].baseURL) {
5404
+ console.log(`Base URL: ${baseURL || PROVIDERS[providerKey].baseURL}`);
5405
+ }
5406
+ }
5407
+ function getProviderKey(choice) {
5408
+ switch (choice) {
5409
+ case "1":
5410
+ return "openai";
5411
+ case "2":
5412
+ return "anthropic";
5413
+ case "3":
5414
+ return "deepseek";
5415
+ case "4":
5416
+ return "openrouter";
5417
+ case "5":
5418
+ return "custom";
5419
+ default:
5420
+ return "openai";
5421
+ }
5422
+ }
5423
+ function question(rl, query) {
5424
+ return new Promise((resolve8) => {
5425
+ rl.question(query, resolve8);
5426
+ });
5427
+ }
5428
+
5308
5429
  // src/cli.ts
5309
5430
  var program = new Command();
5310
- program.name("codemate").description("AI-powered CLI assistant").version("1.0.2");
5431
+ program.name("codemate").description("AI-powered CLI assistant").version("1.0.3");
5311
5432
  program.command("chat", { isDefault: true }).description("Start interactive chat mode").action(async () => {
5312
5433
  try {
5434
+ if (isFirstRun()) {
5435
+ console.log("\n\u6B22\u8FCE\u4F7F\u7528 CodeMate AI! \u{1F389}\n");
5436
+ console.log("\u68C0\u6D4B\u5230\u8FD9\u662F\u9996\u6B21\u8FD0\u884C\uFF0C\u9700\u8981\u8FDB\u884C\u521D\u59CB\u914D\u7F6E\u3002\n");
5437
+ await runFirstTimeSetup();
5438
+ console.log("\n\u914D\u7F6E\u5B8C\u6210\uFF01\u73B0\u5728\u53EF\u4EE5\u5F00\u59CB\u4F7F\u7528\u4E86\u3002\n");
5439
+ console.log('\u8BD5\u8BD5\uFF1Acodemate "\u521B\u5EFA\u4E00\u4E2A Hello World \u7A0B\u5E8F"\n');
5440
+ return;
5441
+ }
5313
5442
  const configService = new ConfigService();
5314
- await configService.load();
5443
+ const configPath = getConfigPath();
5444
+ await configService.load(configPath);
5315
5445
  const app = new Application(void 0, configService);
5316
5446
  await app.start();
5317
5447
  const sessionService = app.getContainer().get("session");
@@ -5324,12 +5454,34 @@ program.command("chat", { isDefault: true }).description("Start interactive chat
5324
5454
  process.exit(1);
5325
5455
  }
5326
5456
  });
5457
+ program.command("config").description("Configure or reconfigure CodeMate AI").action(async () => {
5458
+ try {
5459
+ console.log("\n\u{1F527} CodeMate AI \u914D\u7F6E\u5411\u5BFC\n");
5460
+ if (!isFirstRun()) {
5461
+ console.log("\u5F53\u524D\u914D\u7F6E\u6587\u4EF6: ~/.aiclirc.json");
5462
+ console.log("\u6B64\u64CD\u4F5C\u5C06\u8986\u76D6\u73B0\u6709\u914D\u7F6E\u3002\n");
5463
+ }
5464
+ await runFirstTimeSetup();
5465
+ console.log("\n\u2705 \u914D\u7F6E\u5DF2\u66F4\u65B0\uFF01\n");
5466
+ console.log("\u73B0\u5728\u53EF\u4EE5\u4F7F\u7528 codemate \u5F00\u59CB\u5DE5\u4F5C\u4E86\u3002\n");
5467
+ } catch (error) {
5468
+ console.error("\u274C \u914D\u7F6E\u5931\u8D25:", error);
5469
+ process.exit(1);
5470
+ }
5471
+ });
5327
5472
  program.command("server").description("Start HTTP server mode").option("-p, --port <port>", "Port to listen on", "3000").action(async (options) => {
5328
5473
  try {
5474
+ if (isFirstRun()) {
5475
+ console.log("\n\u274C \u9519\u8BEF\uFF1A\u5C1A\u672A\u914D\u7F6E CodeMate AI\n");
5476
+ console.log("\u8BF7\u5148\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u8FDB\u884C\u914D\u7F6E\uFF1A\n");
5477
+ console.log(" codemate config\n");
5478
+ process.exit(1);
5479
+ }
5329
5480
  const configService = new ConfigService();
5330
- await configService.load();
5481
+ const configPath = getConfigPath();
5482
+ await configService.load(configPath);
5331
5483
  const app = new Application(void 0, configService);
5332
- const port = parseInt(options.port, 10);
5484
+ const port = Number.parseInt(options.port, 10);
5333
5485
  await app.startServer(port);
5334
5486
  process.on("SIGINT", async () => {
5335
5487
  console.log("\n\n\u{1F44B} Shutting down server...");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codemate-ai",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "type": "module",
5
5
  "description": "Enterprise-grade AI coding assistant CLI",
6
6
  "main": "dist/cli.js",