@ww_nero/mini-cli 1.0.60 → 1.0.61

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 ADDED
@@ -0,0 +1,24 @@
1
+ # Mini CLI
2
+
3
+ 极简的 AI 命令行助手,支持工具调用、上下文压缩以及会话历史管理。
4
+
5
+ ## 快速开始
6
+ - 安装依赖:`npm install`
7
+ - 填写配置:首次运行会在 `~/.mini` 生成 `chat.json` 等文件,修改其中的 `key` 为你的接口密钥即可。
8
+ - 运行方式:`npm start` 或 `node bin/mini.js`,也可在全局安装后直接执行 `mini`。
9
+
10
+ ## 常用启动参数
11
+ - `mini -i "你好"`:启动后立即发送首条问题。
12
+ - `mini -m <model>`:指定默认模型(等同于会话内的 `/model <name>`)。
13
+ - `mini --resume`:启动时自动恢复当前工作目录最近一次对话。
14
+ - `mini --help`:查看全部参数说明。
15
+
16
+ ## 对话内快捷命令
17
+ - `/model`:查看或切换模型。
18
+ - `/clear`:清空上下文。
19
+ - `/resume [序号]`:列出或恢复历史会话。
20
+ - `/exit`:退出对话。
21
+
22
+ ## 会话历史
23
+ - 每个工作目录的历史记录保存在 `~/.mini/cli/<workspace-hash>/YYYYMMDDHHMMSS.json` 中。
24
+ - 可通过 `mini --resume` 自动载入最近一次会话,或在对话中使用 `/resume` 按序号恢复。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ww_nero/mini-cli",
3
- "version": "1.0.60",
3
+ "version": "1.0.61",
4
4
  "description": "极简的 AI 命令行助手",
5
5
  "bin": {
6
6
  "mini": "bin/mini.js"
package/src/chat.js CHANGED
@@ -173,6 +173,7 @@ const setLoadingCursorState = (isLoading) => {
173
173
  const startChatSession = async ({
174
174
  initialQuestion = '',
175
175
  initialModelName,
176
+ initialResume = false,
176
177
  cliOptions = []
177
178
  } = {}) => {
178
179
  const initResult = ensureConfigFiles();
@@ -423,6 +424,38 @@ const startChatSession = async ({
423
424
  console.log(chalk.gray('-------- 历史会话结束,可继续提问 --------'));
424
425
  };
425
426
 
427
+ const resumeHistoryByIndex = (index = 0, { auto = false } = {}) => {
428
+ const entries = listHistoryFiles(workspaceRoot);
429
+
430
+ if (entries.length === 0) {
431
+ const notice = auto
432
+ ? '未找到可恢复的历史记录,将开始新的会话。'
433
+ : '暂无历史记录。';
434
+ console.log(chalk.yellow(notice));
435
+ return false;
436
+ }
437
+
438
+ const target = entries[index];
439
+ if (!target) {
440
+ console.log(chalk.yellow(`序号 ${index + 1} 超出范围,当前共有 ${entries.length} 条历史记录。`));
441
+ return false;
442
+ }
443
+
444
+ const historyMessages = readHistoryMessages(target.filePath);
445
+ if (!Array.isArray(historyMessages) || historyMessages.length === 0) {
446
+ console.log(chalk.yellow('该历史记录为空或已损坏,无法恢复。'));
447
+ return false;
448
+ }
449
+
450
+ const refreshedPath = refreshHistoryFilePath(target.filePath, workspaceRoot) || target.filePath;
451
+ loadHistoryFromFile(refreshedPath, historyMessages);
452
+
453
+ const prefix = auto ? '已自动恢复最近一条历史记录' : `已切换到历史记录 #${index + 1}`;
454
+ console.log(chalk.green(`${prefix},可继续对话。`));
455
+ replayHistoryConversation(historyMessages);
456
+ return true;
457
+ };
458
+
426
459
  const handleResumeCommand = (rawArgs = '') => {
427
460
  const entries = listHistoryFiles(workspaceRoot);
428
461
  if (entries.length === 0) {
@@ -451,22 +484,7 @@ const startChatSession = async ({
451
484
  return;
452
485
  }
453
486
 
454
- const target = entries[numeric - 1];
455
- if (!target) {
456
- console.log(chalk.yellow(`序号 ${numeric} 超出范围,当前共有 ${entries.length} 条历史记录。`));
457
- return;
458
- }
459
-
460
- const historyMessages = readHistoryMessages(target.filePath);
461
- if (!Array.isArray(historyMessages) || historyMessages.length === 0) {
462
- console.log(chalk.yellow('该历史记录为空或已损坏,无法恢复。'));
463
- return;
464
- }
465
-
466
- const refreshedPath = refreshHistoryFilePath(target.filePath, workspaceRoot) || target.filePath;
467
- loadHistoryFromFile(refreshedPath, historyMessages);
468
- console.log(chalk.green(`已切换到历史记录 #${numeric},可继续对话。`));
469
- replayHistoryConversation(historyMessages);
487
+ resumeHistoryByIndex(numeric - 1);
470
488
  };
471
489
 
472
490
  console.log(chalk.blueBright('Mini CLI 已启动,随时输入问题开始提问。'));
@@ -499,6 +517,10 @@ const startChatSession = async ({
499
517
  console.log(chalk.gray(` ${cmd.value} - ${cmd.description}`));
500
518
  });
501
519
 
520
+ if (initialResume) {
521
+ resumeHistoryByIndex(0, { auto: true });
522
+ }
523
+
502
524
  const rl = readline.createInterface({
503
525
  input: process.stdin,
504
526
  output: process.stdout,
package/src/index.js CHANGED
@@ -1,38 +1,39 @@
1
- const { Command } = require('commander');
2
- const chalk = require('chalk');
3
-
4
- const pkg = require('../package.json');
5
- const { startChatSession } = require('./chat');
6
- const { getDefaultConfigPath } = require('./config');
7
- const { CLI_OPTIONS } = require('./utils/cliOptions');
8
-
9
- const run = async () => {
10
- const program = new Command();
11
-
12
- program
13
- .name('mini')
14
- .description('Mini CLI · 极简 AI 命令行助手')
15
- .version(pkg.version, '-v, --version')
16
- .addHelpText('after', `\n退出方法:输入 /exit 或按 Ctrl+C。\n配置模板会自动生成于 ${getDefaultConfigPath()}。`)
17
- .showHelpAfterError('(使用 mini --help 查看完整帮助)')
18
- .action(async (options) => {
19
- await startChatSession({
20
- initialQuestion: options.input || '',
21
- initialModelName: options.model,
22
- cliOptions: CLI_OPTIONS
23
- });
24
- });
25
-
26
- CLI_OPTIONS.forEach((option) => {
27
- program.option(option.flags, option.description);
28
- });
29
-
30
- try {
31
- await program.parseAsync(process.argv);
32
- } catch (error) {
33
- console.error(chalk.red(`Mini CLI 运行失败: ${error.message}`));
34
- process.exitCode = 1;
35
- }
36
- };
37
-
38
- run();
1
+ const { Command } = require('commander');
2
+ const chalk = require('chalk');
3
+
4
+ const pkg = require('../package.json');
5
+ const { startChatSession } = require('./chat');
6
+ const { getDefaultConfigPath } = require('./config');
7
+ const { CLI_OPTIONS } = require('./utils/cliOptions');
8
+
9
+ const run = async () => {
10
+ const program = new Command();
11
+
12
+ program
13
+ .name('mini')
14
+ .description('Mini CLI · 极简 AI 命令行助手')
15
+ .version(pkg.version, '-v, --version')
16
+ .addHelpText('after', `\n退出方法:输入 /exit 或按 Ctrl+C。\n配置模板会自动生成于 ${getDefaultConfigPath()}。`)
17
+ .showHelpAfterError('(使用 mini --help 查看完整帮助)')
18
+ .action(async (options) => {
19
+ await startChatSession({
20
+ initialQuestion: options.input || '',
21
+ initialModelName: options.model,
22
+ initialResume: Boolean(options.resume),
23
+ cliOptions: CLI_OPTIONS
24
+ });
25
+ });
26
+
27
+ CLI_OPTIONS.forEach((option) => {
28
+ program.option(option.flags, option.description);
29
+ });
30
+
31
+ try {
32
+ await program.parseAsync(process.argv);
33
+ } catch (error) {
34
+ console.error(chalk.red(`Mini CLI 运行失败: ${error.message}`));
35
+ process.exitCode = 1;
36
+ }
37
+ };
38
+
39
+ run();
@@ -1,6 +1,7 @@
1
1
  const CLI_OPTIONS = [
2
2
  { flags: '-i, --input <text>', description: '启动后先发送一条问题' },
3
- { flags: '-m, --model <name>', description: '指定启动模型名称(等同于运行 /model <name>)' }
3
+ { flags: '-m, --model <name>', description: '指定启动模型名称(等同于运行 /model <name>)' },
4
+ { flags: '-r, --resume', description: '启动时自动恢复最近一条历史会话' }
4
5
  ];
5
6
 
6
7
  module.exports = {