@indiccoder/mentis-cli 1.1.1 → 1.1.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.
package/dist/index.js CHANGED
@@ -6,10 +6,12 @@ function parseArgs() {
6
6
  const args = process.argv.slice(2);
7
7
  const options = {
8
8
  resume: false,
9
- yolo: false
9
+ yolo: false,
10
+ headless: false
10
11
  };
11
12
  let command = null;
12
- for (const arg of args) {
13
+ for (let i = 0; i < args.length; i++) {
14
+ const arg = args[i];
13
15
  switch (arg) {
14
16
  case 'update':
15
17
  command = 'update';
@@ -20,6 +22,11 @@ function parseArgs() {
20
22
  case '--yolo':
21
23
  options.yolo = true;
22
24
  break;
25
+ case '-p':
26
+ case '--prompt':
27
+ options.headless = true;
28
+ options.headlessPrompt = args[++i] || '';
29
+ break;
23
30
  case '-h':
24
31
  case '--help':
25
32
  console.log(`
@@ -30,14 +37,17 @@ Usage:
30
37
  mentis update Update to latest version
31
38
  mentis --resume Resume last session
32
39
  mentis --yolo Auto-confirm mode (skip confirmations)
40
+ mentis -p "<prompt>" Headless mode (non-interactive)
33
41
 
34
42
  Options:
35
43
  --resume Load latest checkpoint on start
36
44
  --yolo Skip all confirmation prompts
45
+ -p, --prompt <text> Headless mode with prompt
37
46
  -h, --help Show this help message
38
47
 
39
48
  Commands (in REPL):
40
49
  /help Show all available commands
50
+ /clear Clear conversation context
41
51
  /resume Resume last session
42
52
  /init Initialize project with .mentis.md
43
53
  /skills <list|show|create|validate> Manage Agent Skills
@@ -44,6 +44,7 @@ const ConfigManager_1 = require("../config/ConfigManager");
44
44
  const OpenAIClient_1 = require("../llm/OpenAIClient");
45
45
  const ContextManager_1 = require("../context/ContextManager");
46
46
  const UIManager_1 = require("../ui/UIManager");
47
+ const InputBox_1 = require("../ui/InputBox");
47
48
  const FileTools_1 = require("../tools/FileTools");
48
49
  const SearchTools_1 = require("../tools/SearchTools");
49
50
  const PersistentShellTool_1 = require("../tools/PersistentShellTool");
@@ -67,7 +68,7 @@ const marked_1 = require("marked");
67
68
  const marked_terminal_1 = __importDefault(require("marked-terminal"));
68
69
  const HISTORY_FILE = path.join(os.homedir(), '.mentis_history');
69
70
  class ReplManager {
70
- constructor(options = { resume: false, yolo: false }) {
71
+ constructor(options = { resume: false, yolo: false, headless: false }) {
71
72
  this.history = [];
72
73
  this.mode = 'BUILD';
73
74
  this.tools = [];
@@ -193,6 +194,12 @@ class ReplManager {
193
194
  // console.log(chalk.dim(`Initialized ${provider} client with model ${model}`));
194
195
  }
195
196
  async start() {
197
+ // Headless mode: non-interactive, process prompt and exit
198
+ if (this.options.headless && this.options.headlessPrompt) {
199
+ await this.handleChat(this.options.headlessPrompt);
200
+ process.exit(0);
201
+ return;
202
+ }
196
203
  UIManager_1.UIManager.renderDashboard({
197
204
  model: this.currentModelName,
198
205
  mode: this.mode,
@@ -218,46 +225,33 @@ class ReplManager {
218
225
  }
219
226
  catch (e) { }
220
227
  }
228
+ // Initialize InputBox with history
229
+ const inputBox = new InputBox_1.InputBox(commandHistory);
221
230
  while (true) {
222
- // Minimalist Separator
223
- console.log(chalk_1.default.gray('────────────────────────────────────────────────────────────────────────────────'));
224
- // Hint (Claude style puts it below, we put it above for standard terminal compatibility)
225
- console.log(chalk_1.default.dim(' ? for shortcuts'));
226
- const promptText = `> `; // Clean prompt
227
- // Use readline for basic input to support history
228
- const answer = await new Promise((resolve) => {
229
- const rl = readline.createInterface({
230
- input: process.stdin,
231
- output: process.stdout,
232
- history: commandHistory,
233
- historySize: 1000,
234
- prompt: promptText
235
- });
236
- rl.prompt();
237
- rl.on('line', (line) => {
238
- rl.close();
239
- resolve(line);
240
- });
231
+ // Calculate context usage for display
232
+ const usage = this.contextVisualizer.calculateUsage(this.history);
233
+ // Display enhanced input frame
234
+ inputBox.displayFrame({
235
+ messageCount: this.history.length,
236
+ contextPercent: usage.percentage
237
+ });
238
+ // Get styled input
239
+ const answer = await inputBox.prompt({
240
+ showHint: this.history.length === 0,
241
+ hint: 'Type your message or /help for commands'
241
242
  });
242
- // Update history manually or grab from rl?
243
- // rl.history gets updated when user hits enter.
244
- // But we closed rl. We should manually save the input to our tracking array and file.
245
243
  const input = answer.trim();
246
244
  if (input) {
247
- // Update in-memory history (for next readline instance)
248
- // Readline history has newest at 0.
249
- // Avoid duplicates if needed, but standard shell keeps them.
250
- if (commandHistory[0] !== input) {
251
- commandHistory.unshift(input);
252
- }
253
- // Append to file (as standard log, so append at end)
245
+ // Update history via InputBox
246
+ inputBox.addToHistory(input);
247
+ // Append to file
254
248
  try {
255
249
  fs.appendFileSync(HISTORY_FILE, input + '\n');
256
250
  }
257
251
  catch (e) { }
258
252
  }
259
- if (!answer.trim())
260
- continue; // Skip empty but allow it to close readline loop
253
+ if (!input)
254
+ continue;
261
255
  if (input.startsWith('/')) {
262
256
  await this.handleCommand(input);
263
257
  continue;
@@ -361,6 +355,10 @@ class ReplManager {
361
355
  const updater = new UpdateManager();
362
356
  await updater.checkAndPerformUpdate(true);
363
357
  break;
358
+ case '/clear':
359
+ this.history = [];
360
+ console.log(chalk_1.default.green('\n✓ Context cleared\n'));
361
+ break;
364
362
  case '/init':
365
363
  await this.handleInitCommand();
366
364
  break;
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+ /**
3
+ * InputBox - Simple clean input with top line only
4
+ * Bottom line appears after submission (cross-platform compatible)
5
+ */
6
+ var __importDefault = (this && this.__importDefault) || function (mod) {
7
+ return (mod && mod.__esModule) ? mod : { "default": mod };
8
+ };
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.InputBox = void 0;
11
+ const readline_1 = __importDefault(require("readline"));
12
+ const chalk_1 = __importDefault(require("chalk"));
13
+ class InputBox {
14
+ constructor(history = []) {
15
+ this.history = [];
16
+ this.historySize = 1000;
17
+ this.history = history;
18
+ }
19
+ /**
20
+ * Get terminal width
21
+ */
22
+ getTerminalWidth() {
23
+ return process.stdout.columns || 80;
24
+ }
25
+ /**
26
+ * Create horizontal line
27
+ */
28
+ createLine() {
29
+ const width = this.getTerminalWidth();
30
+ return chalk_1.default.gray('─'.repeat(width));
31
+ }
32
+ /**
33
+ * Get user input with horizontal lines around it
34
+ */
35
+ async prompt(options = {}) {
36
+ const { showHint = false, hint } = options;
37
+ // Display top horizontal line
38
+ console.log(this.createLine());
39
+ // Display hint if provided
40
+ if (showHint && hint) {
41
+ console.log(chalk_1.default.dim(` ${hint}`));
42
+ }
43
+ return new Promise((resolve) => {
44
+ // Create readline with simple prompt
45
+ const rl = readline_1.default.createInterface({
46
+ input: process.stdin,
47
+ output: process.stdout,
48
+ prompt: chalk_1.default.cyan('> '),
49
+ history: this.history,
50
+ historySize: this.historySize,
51
+ completer: this.completer.bind(this)
52
+ });
53
+ rl.prompt();
54
+ rl.on('line', (line) => {
55
+ // Display bottom horizontal line after input
56
+ console.log(this.createLine());
57
+ rl.close();
58
+ resolve(line);
59
+ });
60
+ // Handle Ctrl+C
61
+ rl.on('SIGINT', () => {
62
+ console.log(this.createLine());
63
+ rl.close();
64
+ resolve('/exit');
65
+ });
66
+ });
67
+ }
68
+ /**
69
+ * Simple tab completer for commands
70
+ */
71
+ completer(line) {
72
+ const commands = [
73
+ '/help', '/clear', '/exit', '/update', '/config',
74
+ '/init', '/resume', '/skills', '/commands', '/checkpoint',
75
+ '/model', '/use', '/mcp', '/search', '/run', '/commit'
76
+ ];
77
+ const hits = commands.filter(c => c.startsWith(line));
78
+ return [hits.length ? hits : commands, line];
79
+ }
80
+ /**
81
+ * Add input to history
82
+ */
83
+ addToHistory(input) {
84
+ if (!input || input === this.history[0])
85
+ return;
86
+ this.history.unshift(input);
87
+ if (this.history.length > this.historySize) {
88
+ this.history = this.history.slice(0, this.historySize);
89
+ }
90
+ }
91
+ /**
92
+ * Get current history
93
+ */
94
+ getHistory() {
95
+ return this.history;
96
+ }
97
+ /**
98
+ * Display separator and context info before input
99
+ */
100
+ displayFrame(contextInfo) {
101
+ console.log('');
102
+ // Context bar with message count and percentage
103
+ if (contextInfo) {
104
+ const { messageCount, contextPercent } = contextInfo;
105
+ const color = contextPercent < 60 ? chalk_1.default.green : contextPercent < 80 ? chalk_1.default.yellow : chalk_1.default.red;
106
+ const bar = this.createProgressBar(contextPercent);
107
+ console.log(chalk_1.default.dim(` ${bar} ${messageCount} msgs ${color(contextPercent + '%')}`));
108
+ }
109
+ }
110
+ /**
111
+ * Display separator (alias for displayFrame)
112
+ */
113
+ displaySeparator(contextInfo) {
114
+ this.displayFrame(contextInfo);
115
+ }
116
+ /**
117
+ * Create a visual progress bar
118
+ */
119
+ createProgressBar(percentage) {
120
+ const width = 15;
121
+ const filled = Math.round(percentage / 100 * width);
122
+ const empty = width - filled;
123
+ const color = percentage < 60 ? chalk_1.default.green : percentage < 80 ? chalk_1.default.yellow : chalk_1.default.red;
124
+ return color('█'.repeat(filled)) + chalk_1.default.dim('░'.repeat(empty));
125
+ }
126
+ }
127
+ exports.InputBox = InputBox;
@@ -19,12 +19,12 @@ class UIManager {
19
19
  whitespaceBreak: true,
20
20
  });
21
21
  console.log(gradient_string_1.default.pastel.multiline(logoText));
22
- console.log(chalk_1.default.gray(' v1.1.1 - AI Coding Agent'));
22
+ console.log(chalk_1.default.gray(' v1.1.3 - AI Coding Agent'));
23
23
  console.log('');
24
24
  }
25
25
  static renderDashboard(config) {
26
26
  const { model, cwd } = config;
27
- const version = 'v1.1.1';
27
+ const version = 'v1.1.3';
28
28
  // Layout: Left (Status/Welcome) | Right (Tips/Activity)
29
29
  // Total width ~80 chars.
30
30
  // Left ~45, Right ~30.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@indiccoder/mentis-cli",
3
- "version": "1.1.1",
3
+ "version": "1.1.3",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -33,6 +33,7 @@
33
33
  "axios": "^1.13.2",
34
34
  "boxen": "^8.0.1",
35
35
  "chalk": "^5.6.2",
36
+ "cli-cursor": "^5.0.0",
36
37
  "cli-highlight": "^2.1.11",
37
38
  "commander": "^14.0.2",
38
39
  "dotenv": "^17.2.3",
@@ -54,6 +55,7 @@
54
55
  "yaml": "^2.7.0"
55
56
  },
56
57
  "devDependencies": {
58
+ "@types/cli-cursor": "^2.1.0",
57
59
  "@types/figlet": "^1.7.0",
58
60
  "@types/fs-extra": "^11.0.4",
59
61
  "@types/gradient-string": "^1.1.6",
package/src/index.ts CHANGED
@@ -4,18 +4,22 @@ import { ReplManager } from './repl/ReplManager';
4
4
  interface CliOptions {
5
5
  resume: boolean;
6
6
  yolo: boolean;
7
+ headless: boolean;
8
+ headlessPrompt?: string;
7
9
  }
8
10
 
9
11
  function parseArgs(): { command: string | null, options: CliOptions } {
10
12
  const args = process.argv.slice(2);
11
13
  const options: CliOptions = {
12
14
  resume: false,
13
- yolo: false
15
+ yolo: false,
16
+ headless: false
14
17
  };
15
18
 
16
19
  let command: string | null = null;
17
20
 
18
- for (const arg of args) {
21
+ for (let i = 0; i < args.length; i++) {
22
+ const arg = args[i];
19
23
  switch (arg) {
20
24
  case 'update':
21
25
  command = 'update';
@@ -26,6 +30,11 @@ function parseArgs(): { command: string | null, options: CliOptions } {
26
30
  case '--yolo':
27
31
  options.yolo = true;
28
32
  break;
33
+ case '-p':
34
+ case '--prompt':
35
+ options.headless = true;
36
+ options.headlessPrompt = args[++i] || '';
37
+ break;
29
38
  case '-h':
30
39
  case '--help':
31
40
  console.log(`
@@ -36,14 +45,17 @@ Usage:
36
45
  mentis update Update to latest version
37
46
  mentis --resume Resume last session
38
47
  mentis --yolo Auto-confirm mode (skip confirmations)
48
+ mentis -p "<prompt>" Headless mode (non-interactive)
39
49
 
40
50
  Options:
41
51
  --resume Load latest checkpoint on start
42
52
  --yolo Skip all confirmation prompts
53
+ -p, --prompt <text> Headless mode with prompt
43
54
  -h, --help Show this help message
44
55
 
45
56
  Commands (in REPL):
46
57
  /help Show all available commands
58
+ /clear Clear conversation context
47
59
  /resume Resume last session
48
60
  /init Initialize project with .mentis.md
49
61
  /skills <list|show|create|validate> Manage Agent Skills
@@ -7,6 +7,7 @@ import { OpenAIClient } from '../llm/OpenAIClient';
7
7
 
8
8
  import { ContextManager } from '../context/ContextManager';
9
9
  import { UIManager } from '../ui/UIManager';
10
+ import { InputBox } from '../ui/InputBox';
10
11
  import { WriteFileTool, ReadFileTool, ListDirTool } from '../tools/FileTools';
11
12
  import { SearchFileTool } from '../tools/SearchTools';
12
13
  import { PersistentShellTool } from '../tools/PersistentShellTool';
@@ -36,6 +37,8 @@ const HISTORY_FILE = path.join(os.homedir(), '.mentis_history');
36
37
  export interface CliOptions {
37
38
  resume: boolean;
38
39
  yolo: boolean;
40
+ headless: boolean;
41
+ headlessPrompt?: string;
39
42
  }
40
43
 
41
44
  export class ReplManager {
@@ -56,7 +59,7 @@ export class ReplManager {
56
59
  private activeSkill: string | null = null; // Track currently active skill for allowed-tools
57
60
  private options: CliOptions;
58
61
 
59
- constructor(options: CliOptions = { resume: false, yolo: false }) {
62
+ constructor(options: CliOptions = { resume: false, yolo: false, headless: false }) {
60
63
  this.options = options;
61
64
  this.configManager = new ConfigManager();
62
65
  this.contextManager = new ContextManager();
@@ -194,6 +197,13 @@ export class ReplManager {
194
197
  }
195
198
 
196
199
  public async start() {
200
+ // Headless mode: non-interactive, process prompt and exit
201
+ if (this.options.headless && this.options.headlessPrompt) {
202
+ await this.handleChat(this.options.headlessPrompt);
203
+ process.exit(0);
204
+ return;
205
+ }
206
+
197
207
  UIManager.renderDashboard({
198
208
  model: this.currentModelName,
199
209
  mode: this.mode,
@@ -220,53 +230,38 @@ export class ReplManager {
220
230
  } catch (e) { }
221
231
  }
222
232
 
233
+ // Initialize InputBox with history
234
+ const inputBox = new InputBox(commandHistory);
235
+
223
236
  while (true) {
224
- // Minimalist Separator
225
- console.log(chalk.gray('────────────────────────────────────────────────────────────────────────────────'));
226
-
227
- // Hint (Claude style puts it below, we put it above for standard terminal compatibility)
228
- console.log(chalk.dim(' ? for shortcuts'));
229
-
230
- const promptText = `> `; // Clean prompt
231
-
232
- // Use readline for basic input to support history
233
- const answer = await new Promise<string>((resolve) => {
234
- const rl = readline.createInterface({
235
- input: process.stdin,
236
- output: process.stdout,
237
- history: commandHistory,
238
- historySize: 1000,
239
- prompt: promptText
240
- });
237
+ // Calculate context usage for display
238
+ const usage = this.contextVisualizer.calculateUsage(this.history);
241
239
 
242
- rl.prompt();
240
+ // Display enhanced input frame
241
+ inputBox.displayFrame({
242
+ messageCount: this.history.length,
243
+ contextPercent: usage.percentage
244
+ });
243
245
 
244
- rl.on('line', (line) => {
245
- rl.close();
246
- resolve(line);
247
- });
246
+ // Get styled input
247
+ const answer = await inputBox.prompt({
248
+ showHint: this.history.length === 0,
249
+ hint: 'Type your message or /help for commands'
248
250
  });
249
251
 
250
- // Update history manually or grab from rl?
251
- // rl.history gets updated when user hits enter.
252
- // But we closed rl. We should manually save the input to our tracking array and file.
253
252
  const input = answer.trim();
254
253
 
255
254
  if (input) {
256
- // Update in-memory history (for next readline instance)
257
- // Readline history has newest at 0.
258
- // Avoid duplicates if needed, but standard shell keeps them.
259
- if (commandHistory[0] !== input) {
260
- commandHistory.unshift(input);
261
- }
255
+ // Update history via InputBox
256
+ inputBox.addToHistory(input);
262
257
 
263
- // Append to file (as standard log, so append at end)
258
+ // Append to file
264
259
  try {
265
260
  fs.appendFileSync(HISTORY_FILE, input + '\n');
266
261
  } catch (e) { }
267
262
  }
268
263
 
269
- if (!answer.trim()) continue; // Skip empty but allow it to close readline loop
264
+ if (!input) continue;
270
265
 
271
266
  if (input.startsWith('/')) {
272
267
  await this.handleCommand(input);
@@ -371,6 +366,10 @@ export class ReplManager {
371
366
  const updater = new UpdateManager();
372
367
  await updater.checkAndPerformUpdate(true);
373
368
  break;
369
+ case '/clear':
370
+ this.history = [];
371
+ console.log(chalk.green('\n✓ Context cleared\n'));
372
+ break;
374
373
  case '/init':
375
374
  await this.handleInitCommand();
376
375
  break;
@@ -0,0 +1,145 @@
1
+ /**
2
+ * InputBox - Simple clean input with top line only
3
+ * Bottom line appears after submission (cross-platform compatible)
4
+ */
5
+
6
+ import readline from 'readline';
7
+ import chalk from 'chalk';
8
+
9
+ export interface InputBoxOptions {
10
+ placeholder?: string;
11
+ showHint?: boolean;
12
+ hint?: string;
13
+ }
14
+
15
+ export class InputBox {
16
+ private history: string[] = [];
17
+ private historySize: number = 1000;
18
+
19
+ constructor(history: string[] = []) {
20
+ this.history = history;
21
+ }
22
+
23
+ /**
24
+ * Get terminal width
25
+ */
26
+ private getTerminalWidth(): number {
27
+ return process.stdout.columns || 80;
28
+ }
29
+
30
+ /**
31
+ * Create horizontal line
32
+ */
33
+ private createLine(): string {
34
+ const width = this.getTerminalWidth();
35
+ return chalk.gray('─'.repeat(width));
36
+ }
37
+
38
+ /**
39
+ * Get user input with horizontal lines around it
40
+ */
41
+ async prompt(options: InputBoxOptions = {}): Promise<string> {
42
+ const { showHint = false, hint } = options;
43
+
44
+ // Display top horizontal line
45
+ console.log(this.createLine());
46
+
47
+ // Display hint if provided
48
+ if (showHint && hint) {
49
+ console.log(chalk.dim(` ${hint}`));
50
+ }
51
+
52
+ return new Promise<string>((resolve) => {
53
+ // Create readline with simple prompt
54
+ const rl = readline.createInterface({
55
+ input: process.stdin,
56
+ output: process.stdout,
57
+ prompt: chalk.cyan('> '),
58
+ history: this.history,
59
+ historySize: this.historySize,
60
+ completer: this.completer.bind(this)
61
+ });
62
+
63
+ rl.prompt();
64
+
65
+ rl.on('line', (line) => {
66
+ // Display bottom horizontal line after input
67
+ console.log(this.createLine());
68
+ rl.close();
69
+ resolve(line);
70
+ });
71
+
72
+ // Handle Ctrl+C
73
+ rl.on('SIGINT', () => {
74
+ console.log(this.createLine());
75
+ rl.close();
76
+ resolve('/exit');
77
+ });
78
+ });
79
+ }
80
+
81
+ /**
82
+ * Simple tab completer for commands
83
+ */
84
+ private completer(line: string) {
85
+ const commands = [
86
+ '/help', '/clear', '/exit', '/update', '/config',
87
+ '/init', '/resume', '/skills', '/commands', '/checkpoint',
88
+ '/model', '/use', '/mcp', '/search', '/run', '/commit'
89
+ ];
90
+
91
+ const hits = commands.filter(c => c.startsWith(line));
92
+ return [hits.length ? hits : commands, line];
93
+ }
94
+
95
+ /**
96
+ * Add input to history
97
+ */
98
+ addToHistory(input: string): void {
99
+ if (!input || input === this.history[0]) return;
100
+ this.history.unshift(input);
101
+ if (this.history.length > this.historySize) {
102
+ this.history = this.history.slice(0, this.historySize);
103
+ }
104
+ }
105
+
106
+ /**
107
+ * Get current history
108
+ */
109
+ getHistory(): string[] {
110
+ return this.history;
111
+ }
112
+
113
+ /**
114
+ * Display separator and context info before input
115
+ */
116
+ public displayFrame(contextInfo?: { messageCount: number; contextPercent: number }): void {
117
+ console.log('');
118
+
119
+ // Context bar with message count and percentage
120
+ if (contextInfo) {
121
+ const { messageCount, contextPercent } = contextInfo;
122
+ const color = contextPercent < 60 ? chalk.green : contextPercent < 80 ? chalk.yellow : chalk.red;
123
+ const bar = this.createProgressBar(contextPercent);
124
+ console.log(chalk.dim(` ${bar} ${messageCount} msgs ${color(contextPercent + '%')}`));
125
+ }
126
+ }
127
+
128
+ /**
129
+ * Display separator (alias for displayFrame)
130
+ */
131
+ public displaySeparator(contextInfo?: { messageCount: number; contextPercent: number }): void {
132
+ this.displayFrame(contextInfo);
133
+ }
134
+
135
+ /**
136
+ * Create a visual progress bar
137
+ */
138
+ private createProgressBar(percentage: number): string {
139
+ const width = 15;
140
+ const filled = Math.round(percentage / 100 * width);
141
+ const empty = width - filled;
142
+ const color = percentage < 60 ? chalk.green : percentage < 80 ? chalk.yellow : chalk.red;
143
+ return color('█'.repeat(filled)) + chalk.dim('░'.repeat(empty));
144
+ }
145
+ }
@@ -14,13 +14,13 @@ export class UIManager {
14
14
  whitespaceBreak: true,
15
15
  });
16
16
  console.log(gradient.pastel.multiline(logoText));
17
- console.log(chalk.gray(' v1.1.1 - AI Coding Agent'));
17
+ console.log(chalk.gray(' v1.1.3 - AI Coding Agent'));
18
18
  console.log('');
19
19
  }
20
20
 
21
21
  public static renderDashboard(config: { model: string, mode: string, cwd: string }) {
22
22
  const { model, cwd } = config;
23
- const version = 'v1.1.1';
23
+ const version = 'v1.1.3';
24
24
 
25
25
  // Layout: Left (Status/Welcome) | Right (Tips/Activity)
26
26
  // Total width ~80 chars.