@indiccoder/mentis-cli 1.1.0 → 1.1.1
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 +52 -2
- package/dist/repl/ReplManager.js +15 -2
- package/dist/ui/UIManager.js +2 -2
- package/dist/utils/ConversationCompacter.js +15 -12
- package/package.json +1 -1
- package/src/index.ts +62 -2
- package/src/repl/ReplManager.ts +22 -2
- package/src/ui/UIManager.ts +2 -2
- package/src/utils/ConversationCompacter.ts +17 -13
package/dist/index.js
CHANGED
|
@@ -2,14 +2,64 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
const ReplManager_1 = require("./repl/ReplManager");
|
|
5
|
+
function parseArgs() {
|
|
6
|
+
const args = process.argv.slice(2);
|
|
7
|
+
const options = {
|
|
8
|
+
resume: false,
|
|
9
|
+
yolo: false
|
|
10
|
+
};
|
|
11
|
+
let command = null;
|
|
12
|
+
for (const arg of args) {
|
|
13
|
+
switch (arg) {
|
|
14
|
+
case 'update':
|
|
15
|
+
command = 'update';
|
|
16
|
+
break;
|
|
17
|
+
case '--resume':
|
|
18
|
+
options.resume = true;
|
|
19
|
+
break;
|
|
20
|
+
case '--yolo':
|
|
21
|
+
options.yolo = true;
|
|
22
|
+
break;
|
|
23
|
+
case '-h':
|
|
24
|
+
case '--help':
|
|
25
|
+
console.log(`
|
|
26
|
+
Mentis CLI - AI Coding Assistant
|
|
27
|
+
|
|
28
|
+
Usage:
|
|
29
|
+
mentis Start interactive REPL
|
|
30
|
+
mentis update Update to latest version
|
|
31
|
+
mentis --resume Resume last session
|
|
32
|
+
mentis --yolo Auto-confirm mode (skip confirmations)
|
|
33
|
+
|
|
34
|
+
Options:
|
|
35
|
+
--resume Load latest checkpoint on start
|
|
36
|
+
--yolo Skip all confirmation prompts
|
|
37
|
+
-h, --help Show this help message
|
|
38
|
+
|
|
39
|
+
Commands (in REPL):
|
|
40
|
+
/help Show all available commands
|
|
41
|
+
/resume Resume last session
|
|
42
|
+
/init Initialize project with .mentis.md
|
|
43
|
+
/skills <list|show|create|validate> Manage Agent Skills
|
|
44
|
+
/commands <list|create|validate> Manage Custom Commands
|
|
45
|
+
`);
|
|
46
|
+
process.exit(0);
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return { command, options };
|
|
51
|
+
}
|
|
5
52
|
async function main() {
|
|
6
|
-
|
|
53
|
+
const { command, options } = parseArgs();
|
|
54
|
+
// Handle update command
|
|
55
|
+
if (command === 'update') {
|
|
7
56
|
const { UpdateManager } = require('./utils/UpdateManager');
|
|
8
57
|
const updater = new UpdateManager();
|
|
9
58
|
await updater.checkAndPerformUpdate(true);
|
|
10
59
|
return;
|
|
11
60
|
}
|
|
12
|
-
|
|
61
|
+
// Start REPL with options
|
|
62
|
+
const repl = new ReplManager_1.ReplManager(options);
|
|
13
63
|
await repl.start();
|
|
14
64
|
}
|
|
15
65
|
main().catch((error) => {
|
package/dist/repl/ReplManager.js
CHANGED
|
@@ -67,13 +67,14 @@ const marked_1 = require("marked");
|
|
|
67
67
|
const marked_terminal_1 = __importDefault(require("marked-terminal"));
|
|
68
68
|
const HISTORY_FILE = path.join(os.homedir(), '.mentis_history');
|
|
69
69
|
class ReplManager {
|
|
70
|
-
constructor() {
|
|
70
|
+
constructor(options = { resume: false, yolo: false }) {
|
|
71
71
|
this.history = [];
|
|
72
72
|
this.mode = 'BUILD';
|
|
73
73
|
this.tools = [];
|
|
74
74
|
this.mcpClients = [];
|
|
75
75
|
this.currentModelName = 'Unknown';
|
|
76
76
|
this.activeSkill = null; // Track currently active skill for allowed-tools
|
|
77
|
+
this.options = options;
|
|
77
78
|
this.configManager = new ConfigManager_1.ConfigManager();
|
|
78
79
|
this.contextManager = new ContextManager_1.ContextManager();
|
|
79
80
|
this.checkpointManager = new CheckpointManager_1.CheckpointManager();
|
|
@@ -197,6 +198,18 @@ class ReplManager {
|
|
|
197
198
|
mode: this.mode,
|
|
198
199
|
cwd: process.cwd()
|
|
199
200
|
});
|
|
201
|
+
// Auto-resume if --resume flag is set
|
|
202
|
+
if (this.options.resume) {
|
|
203
|
+
const cp = this.checkpointManager.load('latest');
|
|
204
|
+
if (cp) {
|
|
205
|
+
this.history = cp.history;
|
|
206
|
+
console.log(chalk_1.default.green(`\n✓ Resumed session from ${new Date(cp.timestamp).toLocaleString()}`));
|
|
207
|
+
console.log(chalk_1.default.dim(` Messages: ${this.history.length}\n`));
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
console.log(chalk_1.default.yellow('\n⚠ No previous session found to resume.\n'));
|
|
211
|
+
}
|
|
212
|
+
}
|
|
200
213
|
// Load History
|
|
201
214
|
let commandHistory = [];
|
|
202
215
|
if (fs.existsSync(HISTORY_FILE)) {
|
|
@@ -529,7 +542,7 @@ class ReplManager {
|
|
|
529
542
|
// Auto-compact prompt when context is at 80%
|
|
530
543
|
const usage = this.contextVisualizer.calculateUsage(this.history);
|
|
531
544
|
if (usage.percentage >= 80) {
|
|
532
|
-
this.history = await this.conversationCompacter.promptIfCompactNeeded(usage.percentage, this.history, this.modelClient);
|
|
545
|
+
this.history = await this.conversationCompacter.promptIfCompactNeeded(usage.percentage, this.history, this.modelClient, this.options.yolo);
|
|
533
546
|
}
|
|
534
547
|
}
|
|
535
548
|
}
|
package/dist/ui/UIManager.js
CHANGED
|
@@ -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.
|
|
22
|
+
console.log(chalk_1.default.gray(' v1.1.1 - 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.
|
|
27
|
+
const version = 'v1.1.1';
|
|
28
28
|
// Layout: Left (Status/Welcome) | Right (Tips/Activity)
|
|
29
29
|
// Total width ~80 chars.
|
|
30
30
|
// Left ~45, Right ~30.
|
|
@@ -65,30 +65,33 @@ class ConversationCompacter {
|
|
|
65
65
|
/**
|
|
66
66
|
* Prompt user to compact when threshold is reached
|
|
67
67
|
*/
|
|
68
|
-
async promptIfCompactNeeded(percentage, history, modelClient) {
|
|
68
|
+
async promptIfCompactNeeded(percentage, history, modelClient, yolo = false) {
|
|
69
69
|
if (percentage < 80) {
|
|
70
70
|
return history;
|
|
71
71
|
}
|
|
72
72
|
console.log(chalk_1.default.yellow(`\n⚠️ Context is ${percentage}% full. Consider compacting to save tokens.`));
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
73
|
+
// Skip confirmation if yolo mode is enabled
|
|
74
|
+
if (!yolo) {
|
|
75
|
+
const { shouldCompact } = await inquirer_1.default.prompt([
|
|
76
|
+
{
|
|
77
|
+
type: 'confirm',
|
|
78
|
+
name: 'shouldCompact',
|
|
79
|
+
message: 'Compact conversation now?',
|
|
80
|
+
default: true
|
|
81
|
+
}
|
|
82
|
+
]);
|
|
83
|
+
if (!shouldCompact) {
|
|
84
|
+
return history;
|
|
79
85
|
}
|
|
80
|
-
]);
|
|
81
|
-
if (!shouldCompact) {
|
|
82
|
-
return history;
|
|
83
86
|
}
|
|
84
|
-
const
|
|
87
|
+
const focusTopic = yolo ? '' : await inquirer_1.default.prompt([
|
|
85
88
|
{
|
|
86
89
|
type: 'input',
|
|
87
90
|
name: 'focusTopic',
|
|
88
91
|
message: 'Focus on specific topic? (leave empty for general)',
|
|
89
92
|
default: ''
|
|
90
93
|
}
|
|
91
|
-
]);
|
|
94
|
+
]).then(a => a.focusTopic);
|
|
92
95
|
return await this.compact(history, modelClient, {
|
|
93
96
|
keepSystemMessages: true,
|
|
94
97
|
focusTopic: focusTopic || undefined
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,15 +1,75 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { ReplManager } from './repl/ReplManager';
|
|
3
3
|
|
|
4
|
+
interface CliOptions {
|
|
5
|
+
resume: boolean;
|
|
6
|
+
yolo: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function parseArgs(): { command: string | null, options: CliOptions } {
|
|
10
|
+
const args = process.argv.slice(2);
|
|
11
|
+
const options: CliOptions = {
|
|
12
|
+
resume: false,
|
|
13
|
+
yolo: false
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
let command: string | null = null;
|
|
17
|
+
|
|
18
|
+
for (const arg of args) {
|
|
19
|
+
switch (arg) {
|
|
20
|
+
case 'update':
|
|
21
|
+
command = 'update';
|
|
22
|
+
break;
|
|
23
|
+
case '--resume':
|
|
24
|
+
options.resume = true;
|
|
25
|
+
break;
|
|
26
|
+
case '--yolo':
|
|
27
|
+
options.yolo = true;
|
|
28
|
+
break;
|
|
29
|
+
case '-h':
|
|
30
|
+
case '--help':
|
|
31
|
+
console.log(`
|
|
32
|
+
Mentis CLI - AI Coding Assistant
|
|
33
|
+
|
|
34
|
+
Usage:
|
|
35
|
+
mentis Start interactive REPL
|
|
36
|
+
mentis update Update to latest version
|
|
37
|
+
mentis --resume Resume last session
|
|
38
|
+
mentis --yolo Auto-confirm mode (skip confirmations)
|
|
39
|
+
|
|
40
|
+
Options:
|
|
41
|
+
--resume Load latest checkpoint on start
|
|
42
|
+
--yolo Skip all confirmation prompts
|
|
43
|
+
-h, --help Show this help message
|
|
44
|
+
|
|
45
|
+
Commands (in REPL):
|
|
46
|
+
/help Show all available commands
|
|
47
|
+
/resume Resume last session
|
|
48
|
+
/init Initialize project with .mentis.md
|
|
49
|
+
/skills <list|show|create|validate> Manage Agent Skills
|
|
50
|
+
/commands <list|create|validate> Manage Custom Commands
|
|
51
|
+
`);
|
|
52
|
+
process.exit(0);
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return { command, options };
|
|
58
|
+
}
|
|
59
|
+
|
|
4
60
|
async function main() {
|
|
5
|
-
|
|
61
|
+
const { command, options } = parseArgs();
|
|
62
|
+
|
|
63
|
+
// Handle update command
|
|
64
|
+
if (command === 'update') {
|
|
6
65
|
const { UpdateManager } = require('./utils/UpdateManager');
|
|
7
66
|
const updater = new UpdateManager();
|
|
8
67
|
await updater.checkAndPerformUpdate(true);
|
|
9
68
|
return;
|
|
10
69
|
}
|
|
11
70
|
|
|
12
|
-
|
|
71
|
+
// Start REPL with options
|
|
72
|
+
const repl = new ReplManager(options);
|
|
13
73
|
await repl.start();
|
|
14
74
|
}
|
|
15
75
|
|
package/src/repl/ReplManager.ts
CHANGED
|
@@ -33,6 +33,11 @@ import TerminalRenderer from 'marked-terminal';
|
|
|
33
33
|
|
|
34
34
|
const HISTORY_FILE = path.join(os.homedir(), '.mentis_history');
|
|
35
35
|
|
|
36
|
+
export interface CliOptions {
|
|
37
|
+
resume: boolean;
|
|
38
|
+
yolo: boolean;
|
|
39
|
+
}
|
|
40
|
+
|
|
36
41
|
export class ReplManager {
|
|
37
42
|
private configManager: ConfigManager;
|
|
38
43
|
private modelClient!: ModelClient;
|
|
@@ -49,8 +54,10 @@ export class ReplManager {
|
|
|
49
54
|
private shell: PersistentShell;
|
|
50
55
|
private currentModelName: string = 'Unknown';
|
|
51
56
|
private activeSkill: string | null = null; // Track currently active skill for allowed-tools
|
|
57
|
+
private options: CliOptions;
|
|
52
58
|
|
|
53
|
-
constructor() {
|
|
59
|
+
constructor(options: CliOptions = { resume: false, yolo: false }) {
|
|
60
|
+
this.options = options;
|
|
54
61
|
this.configManager = new ConfigManager();
|
|
55
62
|
this.contextManager = new ContextManager();
|
|
56
63
|
this.checkpointManager = new CheckpointManager();
|
|
@@ -193,6 +200,18 @@ export class ReplManager {
|
|
|
193
200
|
cwd: process.cwd()
|
|
194
201
|
});
|
|
195
202
|
|
|
203
|
+
// Auto-resume if --resume flag is set
|
|
204
|
+
if (this.options.resume) {
|
|
205
|
+
const cp = this.checkpointManager.load('latest');
|
|
206
|
+
if (cp) {
|
|
207
|
+
this.history = cp.history;
|
|
208
|
+
console.log(chalk.green(`\n✓ Resumed session from ${new Date(cp.timestamp).toLocaleString()}`));
|
|
209
|
+
console.log(chalk.dim(` Messages: ${this.history.length}\n`));
|
|
210
|
+
} else {
|
|
211
|
+
console.log(chalk.yellow('\n⚠ No previous session found to resume.\n'));
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
196
215
|
// Load History
|
|
197
216
|
let commandHistory: string[] = [];
|
|
198
217
|
if (fs.existsSync(HISTORY_FILE)) {
|
|
@@ -565,7 +584,8 @@ export class ReplManager {
|
|
|
565
584
|
this.history = await this.conversationCompacter.promptIfCompactNeeded(
|
|
566
585
|
usage.percentage,
|
|
567
586
|
this.history,
|
|
568
|
-
this.modelClient
|
|
587
|
+
this.modelClient,
|
|
588
|
+
this.options.yolo
|
|
569
589
|
);
|
|
570
590
|
}
|
|
571
591
|
}
|
package/src/ui/UIManager.ts
CHANGED
|
@@ -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.
|
|
17
|
+
console.log(chalk.gray(' v1.1.1 - 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.
|
|
23
|
+
const version = 'v1.1.1';
|
|
24
24
|
|
|
25
25
|
// Layout: Left (Status/Welcome) | Right (Tips/Activity)
|
|
26
26
|
// Total width ~80 chars.
|
|
@@ -86,7 +86,8 @@ export class ConversationCompacter {
|
|
|
86
86
|
async promptIfCompactNeeded(
|
|
87
87
|
percentage: number,
|
|
88
88
|
history: ChatMessage[],
|
|
89
|
-
modelClient: ModelClient
|
|
89
|
+
modelClient: ModelClient,
|
|
90
|
+
yolo: boolean = false
|
|
90
91
|
): Promise<ChatMessage[]> {
|
|
91
92
|
if (percentage < 80) {
|
|
92
93
|
return history;
|
|
@@ -94,27 +95,30 @@ export class ConversationCompacter {
|
|
|
94
95
|
|
|
95
96
|
console.log(chalk.yellow(`\n⚠️ Context is ${percentage}% full. Consider compacting to save tokens.`));
|
|
96
97
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
98
|
+
// Skip confirmation if yolo mode is enabled
|
|
99
|
+
if (!yolo) {
|
|
100
|
+
const { shouldCompact } = await inquirer.prompt([
|
|
101
|
+
{
|
|
102
|
+
type: 'confirm',
|
|
103
|
+
name: 'shouldCompact',
|
|
104
|
+
message: 'Compact conversation now?',
|
|
105
|
+
default: true
|
|
106
|
+
}
|
|
107
|
+
]);
|
|
108
|
+
|
|
109
|
+
if (!shouldCompact) {
|
|
110
|
+
return history;
|
|
103
111
|
}
|
|
104
|
-
]);
|
|
105
|
-
|
|
106
|
-
if (!shouldCompact) {
|
|
107
|
-
return history;
|
|
108
112
|
}
|
|
109
113
|
|
|
110
|
-
const
|
|
114
|
+
const focusTopic = yolo ? '' : await inquirer.prompt([
|
|
111
115
|
{
|
|
112
116
|
type: 'input',
|
|
113
117
|
name: 'focusTopic',
|
|
114
118
|
message: 'Focus on specific topic? (leave empty for general)',
|
|
115
119
|
default: ''
|
|
116
120
|
}
|
|
117
|
-
]);
|
|
121
|
+
]).then(a => a.focusTopic);
|
|
118
122
|
|
|
119
123
|
return await this.compact(history, modelClient, {
|
|
120
124
|
keepSystemMessages: true,
|