@pheem49/mint 1.2.2 โ 1.2.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 +4 -3
- package/docs/assets/Agent_Mint.png +0 -0
- package/docs/assets/Settings.png +0 -0
- package/docs/assets/icon.png +0 -0
- package/docs/index.html +53 -5
- package/docs/style.css +295 -6
- package/mint-cli-logic.js +2 -0
- package/mint-cli.js +61 -45
- package/package.json +1 -1
- package/src/AI_Brain/Gemini_API.js +2 -2
- package/src/AI_Brain/autonomous_brain.js +1 -1
- package/src/AI_Brain/proactive_engine.js +1 -1
- package/src/Automation_Layer/browser_automation.js +1 -1
- package/src/Automation_Layer/file_operations.js +50 -8
- package/src/CLI/chat_ui.js +50 -19
- package/src/Plugins/plugin_manager.js +2 -2
- package/src/System/system_automation.js +28 -0
- package/src/UI/settings.js +1 -1
- package/docs/assets/hero-bg.png +0 -0
- package/docs/assets/logo.png +0 -0
package/README.md
CHANGED
|
@@ -22,8 +22,9 @@
|
|
|
22
22
|
## ๐ Highlights
|
|
23
23
|
|
|
24
24
|
- **Dual-Mode AI**: Switch between a beautiful **Desktop GUI** and a professional **CLI**.
|
|
25
|
-
- **Interactive Slash Commands**: Manage models and settings in the terminal with `/
|
|
26
|
-
- **
|
|
25
|
+
- **Interactive Slash Commands**: Manage models and settings in the terminal with `/model`, `/config`, `/clear`, etc.
|
|
26
|
+
- **Smart TUI Experience**: Professional message framing, character-wrapped Thai text support, and mouse scroll wheel navigation.
|
|
27
|
+
- **System Information Action**: Retrieve OS, Kernel, and Architecture details via natural language.
|
|
27
28
|
- **Dynamic UI Aesthetics**: Animated **Aura Glow** for the AI widget and **Glassmorphism** design.
|
|
28
29
|
- **Minimize-to-Tray**: Keep Mint running in the background via the System Tray.
|
|
29
30
|
- **Vision-Ready (Desktop)**: Capture, analyze, and translate any part of your screen in real-time.
|
|
@@ -131,7 +132,7 @@ When running in `agent` mode, Mint monitors your system in the background:
|
|
|
131
132
|
### Installation
|
|
132
133
|
1. **Install via NPM (Recommended)**
|
|
133
134
|
```bash
|
|
134
|
-
npm install -g @pheem49/mint
|
|
135
|
+
npm install -g @pheem49/mint@latest
|
|
135
136
|
```
|
|
136
137
|
|
|
137
138
|
2. **Manual Installation (For Developers)**
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/docs/index.html
CHANGED
|
@@ -7,14 +7,18 @@
|
|
|
7
7
|
<meta name="description" content="A powerful Electron-based AI desktop assistant powered by Google Gemini, featuring screen vision, web automation, and proactive suggestions.">
|
|
8
8
|
<link rel="stylesheet" href="style.css">
|
|
9
9
|
<script src="https://unpkg.com/@phosphor-icons/web"></script>
|
|
10
|
-
<link rel="icon" type="image/png" href="assets/
|
|
10
|
+
<link rel="icon" type="image/png" href="assets/icon.png">
|
|
11
11
|
</head>
|
|
12
12
|
<body>
|
|
13
13
|
<div class="bg-glow"></div>
|
|
14
|
-
|
|
14
|
+
<div class="floating-blobs">
|
|
15
|
+
<div class="blob blob-1"></div>
|
|
16
|
+
<div class="blob blob-2"></div>
|
|
17
|
+
<div class="blob blob-3"></div>
|
|
18
|
+
</div>
|
|
15
19
|
<nav>
|
|
16
20
|
<div class="logo-container">
|
|
17
|
-
<img src="assets/
|
|
21
|
+
<img src="assets/icon.png" alt="Mint Logo">
|
|
18
22
|
<span>Agent Mint</span>
|
|
19
23
|
</div>
|
|
20
24
|
<div class="nav-links">
|
|
@@ -30,15 +34,59 @@
|
|
|
30
34
|
|
|
31
35
|
<div class="install-container" id="install-cmd">
|
|
32
36
|
<span>$</span>
|
|
33
|
-
<code>npm install -g @pheem49/mint</code>
|
|
37
|
+
<code>npm install -g @pheem49/mint@latest</code>
|
|
34
38
|
<button class="copy-btn" title="Copy to clipboard" onclick="copyCommand()">
|
|
35
39
|
<i class="ph ph-copy"></i>
|
|
36
40
|
</button>
|
|
37
41
|
</div>
|
|
38
42
|
|
|
39
43
|
<div class="hero-preview">
|
|
44
|
+
<div class="preview-badge">Terminal Interface</div>
|
|
40
45
|
<img src="assets/CLI_Screen.png" alt="Mint CLI Preview">
|
|
41
46
|
</div>
|
|
47
|
+
|
|
48
|
+
<section class="desktop-showcase">
|
|
49
|
+
<div class="showcase-header">
|
|
50
|
+
<img src="assets/icon.png" alt="Mint Icon" class="section-icon">
|
|
51
|
+
<h2>Modern Desktop Interface</h2>
|
|
52
|
+
<p>Enjoy a premium, glassmorphism-inspired GUI designed for the modern desktop environment. Manage your AI companion and customize your experience with ease.</p>
|
|
53
|
+
</div>
|
|
54
|
+
|
|
55
|
+
<div class="showcase-group">
|
|
56
|
+
<div class="showcase-images">
|
|
57
|
+
<div class="image-wrapper main-ui">
|
|
58
|
+
<img src="assets/Agent_Mint.png" alt="Agent Mint Main UI">
|
|
59
|
+
<span>Main Interface</span>
|
|
60
|
+
</div>
|
|
61
|
+
<div class="image-wrapper settings-ui">
|
|
62
|
+
<img src="assets/Settings.png" alt="Mint Settings UI">
|
|
63
|
+
<span>Settings & Controls</span>
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
|
|
67
|
+
<div class="showcase-text-combined">
|
|
68
|
+
<div class="text-block">
|
|
69
|
+
<h3><i class="ph ph-sparkle"></i> Intelligent Companion</h3>
|
|
70
|
+
<p>A sleek, floating chat interface that provides powerful AI capabilities without cluttering your workspace.</p>
|
|
71
|
+
</div>
|
|
72
|
+
<div class="text-block">
|
|
73
|
+
<h3><i class="ph ph-sliders"></i> Granular Controls</h3>
|
|
74
|
+
<p>Fully customize your experience. Manage API keys, switch models, and toggle proactive features with ease.</p>
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
</section>
|
|
79
|
+
|
|
80
|
+
<section class="downloads">
|
|
81
|
+
<div class="download-container">
|
|
82
|
+
<h2>Get the Latest Release</h2>
|
|
83
|
+
<p>Download the latest stable binaries for Linux including <b>.deb</b> and <b>.AppImage</b> formats directly from our GitHub releases page.</p>
|
|
84
|
+
<a href="https://github.com/Pheem49/Mint/releases" class="download-btn" target="_blank">
|
|
85
|
+
<i class="ph ph-download-simple"></i>
|
|
86
|
+
Download Latest Binaries
|
|
87
|
+
</a>
|
|
88
|
+
</div>
|
|
89
|
+
</section>
|
|
42
90
|
</header>
|
|
43
91
|
|
|
44
92
|
<section class="features" id="features">
|
|
@@ -71,7 +119,7 @@
|
|
|
71
119
|
|
|
72
120
|
<script>
|
|
73
121
|
function copyCommand() {
|
|
74
|
-
const cmd = "npm install -g @pheem49/mint";
|
|
122
|
+
const cmd = "npm install -g @pheem49/mint@latest";
|
|
75
123
|
navigator.clipboard.writeText(cmd);
|
|
76
124
|
const icon = document.querySelector('.copy-btn i');
|
|
77
125
|
icon.classList.replace('ph-copy', 'ph-check');
|
package/docs/style.css
CHANGED
|
@@ -31,7 +31,7 @@ body {
|
|
|
31
31
|
overflow-x: hidden;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
/* Background Gradients */
|
|
34
|
+
/* Background Gradients & Texture */
|
|
35
35
|
.bg-glow {
|
|
36
36
|
position: fixed;
|
|
37
37
|
top: 0;
|
|
@@ -39,8 +39,78 @@ body {
|
|
|
39
39
|
width: 100%;
|
|
40
40
|
height: 100%;
|
|
41
41
|
z-index: -1;
|
|
42
|
-
background:
|
|
43
|
-
|
|
42
|
+
background:
|
|
43
|
+
radial-gradient(circle at 0% 0%, rgba(0, 255, 163, 0.03) 0%, transparent 40%),
|
|
44
|
+
radial-gradient(circle at 100% 100%, rgba(0, 224, 255, 0.03) 0%, transparent 40%),
|
|
45
|
+
var(--bg-color);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.bg-glow::before {
|
|
49
|
+
content: '';
|
|
50
|
+
position: absolute;
|
|
51
|
+
top: 0;
|
|
52
|
+
left: 0;
|
|
53
|
+
width: 100%;
|
|
54
|
+
height: 100%;
|
|
55
|
+
background-image: radial-gradient(rgba(255, 255, 255, 0.03) 1px, transparent 1px);
|
|
56
|
+
background-size: 40px 40px;
|
|
57
|
+
opacity: 0.5;
|
|
58
|
+
mask-image: radial-gradient(ellipse at center, black, transparent 80%);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/* Floating Blobs */
|
|
62
|
+
.floating-blobs {
|
|
63
|
+
position: fixed;
|
|
64
|
+
top: 0;
|
|
65
|
+
left: 0;
|
|
66
|
+
width: 100%;
|
|
67
|
+
height: 100%;
|
|
68
|
+
z-index: -1;
|
|
69
|
+
overflow: hidden;
|
|
70
|
+
pointer-events: none;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.blob {
|
|
74
|
+
position: absolute;
|
|
75
|
+
border-radius: 50%;
|
|
76
|
+
filter: blur(120px);
|
|
77
|
+
opacity: 0.15;
|
|
78
|
+
animation: float 20s infinite alternate cubic-bezier(0.45, 0, 0.55, 1);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.blob-1 {
|
|
82
|
+
width: 600px;
|
|
83
|
+
height: 600px;
|
|
84
|
+
background: var(--accent-mint);
|
|
85
|
+
top: -200px;
|
|
86
|
+
left: -100px;
|
|
87
|
+
animation-duration: 25s;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.blob-2 {
|
|
91
|
+
width: 500px;
|
|
92
|
+
height: 500px;
|
|
93
|
+
background: var(--accent-blue);
|
|
94
|
+
bottom: -100px;
|
|
95
|
+
right: -100px;
|
|
96
|
+
animation-duration: 30s;
|
|
97
|
+
animation-delay: -5s;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.blob-3 {
|
|
101
|
+
width: 400px;
|
|
102
|
+
height: 400px;
|
|
103
|
+
background: #8b5cf6;
|
|
104
|
+
top: 40%;
|
|
105
|
+
left: 50%;
|
|
106
|
+
opacity: 0.08;
|
|
107
|
+
animation-duration: 22s;
|
|
108
|
+
animation-delay: -10s;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
@keyframes float {
|
|
112
|
+
0% { transform: translate(0, 0) scale(1); }
|
|
113
|
+
100% { transform: translate(100px, 50px) scale(1.1); }
|
|
44
114
|
}
|
|
45
115
|
|
|
46
116
|
/* Navigation */
|
|
@@ -99,15 +169,13 @@ nav {
|
|
|
99
169
|
|
|
100
170
|
/* Hero Section */
|
|
101
171
|
.hero {
|
|
102
|
-
min-height:
|
|
172
|
+
min-height: 90vh;
|
|
103
173
|
display: flex;
|
|
104
174
|
flex-direction: column;
|
|
105
175
|
justify-content: center;
|
|
106
176
|
align-items: center;
|
|
107
177
|
text-align: center;
|
|
108
178
|
padding: 120px 20px 60px;
|
|
109
|
-
background: url('assets/hero-bg.png') no-repeat center center;
|
|
110
|
-
background-size: cover;
|
|
111
179
|
position: relative;
|
|
112
180
|
}
|
|
113
181
|
|
|
@@ -119,6 +187,7 @@ nav {
|
|
|
119
187
|
width: 100%;
|
|
120
188
|
height: 300px;
|
|
121
189
|
background: linear-gradient(to top, var(--bg-color), transparent);
|
|
190
|
+
pointer-events: none;
|
|
122
191
|
}
|
|
123
192
|
|
|
124
193
|
.hero h1 {
|
|
@@ -179,6 +248,22 @@ nav {
|
|
|
179
248
|
border: 1px solid rgba(255, 255, 255, 0.05);
|
|
180
249
|
}
|
|
181
250
|
|
|
251
|
+
.preview-badge {
|
|
252
|
+
position: absolute;
|
|
253
|
+
top: -15px;
|
|
254
|
+
left: 50%;
|
|
255
|
+
transform: translateX(-50%);
|
|
256
|
+
background: var(--accent-mint);
|
|
257
|
+
color: #000;
|
|
258
|
+
padding: 0.4rem 1.2rem;
|
|
259
|
+
border-radius: 100px;
|
|
260
|
+
font-size: 0.8rem;
|
|
261
|
+
font-weight: 800;
|
|
262
|
+
text-transform: uppercase;
|
|
263
|
+
letter-spacing: 1px;
|
|
264
|
+
box-shadow: 0 10px 20px rgba(0, 255, 163, 0.3);
|
|
265
|
+
}
|
|
266
|
+
|
|
182
267
|
@keyframes slideUp {
|
|
183
268
|
from {
|
|
184
269
|
opacity: 0;
|
|
@@ -265,6 +350,210 @@ nav {
|
|
|
265
350
|
font-size: 1rem;
|
|
266
351
|
}
|
|
267
352
|
|
|
353
|
+
/* Desktop Showcase */
|
|
354
|
+
.desktop-showcase {
|
|
355
|
+
padding: 100px 10%;
|
|
356
|
+
z-index: 1;
|
|
357
|
+
position: relative;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
.showcase-header {
|
|
361
|
+
text-align: center;
|
|
362
|
+
margin-bottom: 5rem;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
.section-icon {
|
|
366
|
+
width: 64px;
|
|
367
|
+
height: 64px;
|
|
368
|
+
margin-bottom: 1.5rem;
|
|
369
|
+
filter: drop-shadow(0 0 20px rgba(0, 255, 163, 0.4));
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
.showcase-header h2 {
|
|
373
|
+
font-family: var(--font-heading);
|
|
374
|
+
font-size: 3.5rem;
|
|
375
|
+
margin-bottom: 1rem;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
.showcase-header p {
|
|
379
|
+
color: var(--text-secondary);
|
|
380
|
+
font-size: 1.2rem;
|
|
381
|
+
max-width: 600px;
|
|
382
|
+
margin: 0 auto;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
.showcase-group {
|
|
386
|
+
display: flex;
|
|
387
|
+
flex-direction: column;
|
|
388
|
+
align-items: center;
|
|
389
|
+
gap: 4rem;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
.showcase-images {
|
|
393
|
+
display: flex;
|
|
394
|
+
justify-content: center;
|
|
395
|
+
align-items: flex-start;
|
|
396
|
+
gap: 2rem;
|
|
397
|
+
width: 100%;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
.image-wrapper {
|
|
401
|
+
flex: 1;
|
|
402
|
+
max-width: 450px;
|
|
403
|
+
background: rgba(255, 255, 255, 0.02);
|
|
404
|
+
border: 1px solid var(--glass-border);
|
|
405
|
+
padding: 0.75rem;
|
|
406
|
+
border-radius: 20px;
|
|
407
|
+
position: relative;
|
|
408
|
+
backdrop-filter: blur(10px);
|
|
409
|
+
transition: transform 0.4s ease;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
.image-wrapper:hover {
|
|
413
|
+
transform: translateY(-10px);
|
|
414
|
+
border-color: var(--accent-mint);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
.image-wrapper img {
|
|
418
|
+
width: 100%;
|
|
419
|
+
display: block;
|
|
420
|
+
border-radius: 12px;
|
|
421
|
+
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.4);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
.image-wrapper span {
|
|
425
|
+
display: block;
|
|
426
|
+
text-align: center;
|
|
427
|
+
margin-top: 1rem;
|
|
428
|
+
font-size: 0.85rem;
|
|
429
|
+
color: var(--text-secondary);
|
|
430
|
+
font-weight: 500;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
.showcase-text-combined {
|
|
434
|
+
display: grid;
|
|
435
|
+
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
|
436
|
+
gap: 3rem;
|
|
437
|
+
width: 100%;
|
|
438
|
+
max-width: 900px;
|
|
439
|
+
margin-top: 2rem;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
.text-block {
|
|
443
|
+
text-align: left;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
.text-block h3 {
|
|
447
|
+
font-family: var(--font-heading);
|
|
448
|
+
font-size: 1.5rem;
|
|
449
|
+
margin-bottom: 0.75rem;
|
|
450
|
+
color: var(--accent-mint);
|
|
451
|
+
display: flex;
|
|
452
|
+
align-items: center;
|
|
453
|
+
gap: 0.5rem;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
.text-block p {
|
|
457
|
+
font-size: 1rem;
|
|
458
|
+
color: var(--text-secondary);
|
|
459
|
+
line-height: 1.6;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/* Downloads Section */
|
|
463
|
+
.downloads {
|
|
464
|
+
padding: 100px 10% 60px;
|
|
465
|
+
display: flex;
|
|
466
|
+
justify-content: center;
|
|
467
|
+
z-index: 5;
|
|
468
|
+
position: relative;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
.download-container {
|
|
472
|
+
background: linear-gradient(135deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.01));
|
|
473
|
+
border: 1px solid var(--glass-border);
|
|
474
|
+
padding: 3.5rem;
|
|
475
|
+
border-radius: 32px;
|
|
476
|
+
max-width: 800px;
|
|
477
|
+
text-align: center;
|
|
478
|
+
backdrop-filter: blur(15px);
|
|
479
|
+
box-shadow: 0 30px 60px rgba(0, 0, 0, 0.3);
|
|
480
|
+
z-index: 10;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
.download-container h2 {
|
|
484
|
+
font-family: var(--font-heading);
|
|
485
|
+
font-size: 2.5rem;
|
|
486
|
+
margin-bottom: 1.5rem;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
.download-container p {
|
|
490
|
+
color: var(--text-secondary);
|
|
491
|
+
font-size: 1.1rem;
|
|
492
|
+
margin-bottom: 2.5rem;
|
|
493
|
+
line-height: 1.8;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
.download-container b {
|
|
497
|
+
color: var(--text-primary);
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
.download-btn {
|
|
501
|
+
display: inline-flex;
|
|
502
|
+
align-items: center;
|
|
503
|
+
gap: 0.75rem;
|
|
504
|
+
background: var(--accent-mint);
|
|
505
|
+
color: #000;
|
|
506
|
+
text-decoration: none;
|
|
507
|
+
padding: 1.25rem 2.5rem;
|
|
508
|
+
border-radius: 100px;
|
|
509
|
+
font-weight: 700;
|
|
510
|
+
font-size: 1.1rem;
|
|
511
|
+
transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
|
512
|
+
box-shadow: 0 10px 30px rgba(0, 255, 163, 0.3);
|
|
513
|
+
cursor: pointer;
|
|
514
|
+
position: relative;
|
|
515
|
+
z-index: 11;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
.download-btn:hover {
|
|
519
|
+
transform: scale(1.05);
|
|
520
|
+
box-shadow: 0 15px 40px rgba(0, 255, 163, 0.5);
|
|
521
|
+
background: #fff;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
.download-btn i {
|
|
525
|
+
font-size: 1.4rem;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
.download-card h4 {
|
|
529
|
+
font-family: var(--font-heading);
|
|
530
|
+
font-size: 1.25rem;
|
|
531
|
+
margin-bottom: 1rem;
|
|
532
|
+
display: flex;
|
|
533
|
+
align-items: center;
|
|
534
|
+
gap: 0.75rem;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
.download-card h4 i {
|
|
538
|
+
color: var(--accent-blue);
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
.download-card pre {
|
|
542
|
+
background: #000;
|
|
543
|
+
padding: 1rem;
|
|
544
|
+
border-radius: 8px;
|
|
545
|
+
font-size: 0.9rem;
|
|
546
|
+
color: var(--accent-mint);
|
|
547
|
+
margin-top: 1rem;
|
|
548
|
+
overflow-x: auto;
|
|
549
|
+
border: 1px solid rgba(255, 255, 255, 0.05);
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
.download-card p {
|
|
553
|
+
color: var(--text-secondary);
|
|
554
|
+
font-size: 0.95rem;
|
|
555
|
+
}
|
|
556
|
+
|
|
268
557
|
/* Footer */
|
|
269
558
|
footer {
|
|
270
559
|
padding: 60px 10% 40px;
|
package/mint-cli-logic.js
CHANGED
|
@@ -35,6 +35,8 @@ async function executeAction(action) {
|
|
|
35
35
|
return await pluginManager.executePlugin(action.pluginName, action.target);
|
|
36
36
|
case 'system_automation':
|
|
37
37
|
return await handleSystemAutomation(action.target);
|
|
38
|
+
case 'system_info':
|
|
39
|
+
return await SystemAutomation.getSystemInfo(action.target);
|
|
38
40
|
default:
|
|
39
41
|
return `Action ${action.type} is not yet fully supported in CLI.`;
|
|
40
42
|
}
|
package/mint-cli.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
require('dotenv').config();
|
|
2
|
+
require('dotenv').config({ quiet: true });
|
|
3
3
|
const { Command } = require('commander');
|
|
4
4
|
const { handleChat, resetChat } = require('./src/AI_Brain/Gemini_API');
|
|
5
|
+
const pkg = require('./package.json');
|
|
5
6
|
const { runOnboarding } = require('./src/CLI/onboarding');
|
|
6
7
|
const { startAgent } = require('./src/AI_Brain/headless_agent');
|
|
7
8
|
const { displayFeatures } = require('./src/CLI/list_features');
|
|
@@ -9,6 +10,16 @@ const { readConfig, writeConfig } = require('./src/System/config_manager');
|
|
|
9
10
|
const readline = require('readline');
|
|
10
11
|
const { createChatUI } = require('./src/CLI/chat_ui');
|
|
11
12
|
|
|
13
|
+
// Startup Info
|
|
14
|
+
const startupConfig = readConfig();
|
|
15
|
+
const startupModel = startupConfig.geminiModel || 'gemini-2.5-flash';
|
|
16
|
+
const startupNow = new Date();
|
|
17
|
+
const startupTime = startupNow.toLocaleString('th-TH', {
|
|
18
|
+
day: '2-digit', month: '2-digit', year: 'numeric',
|
|
19
|
+
hour: '2-digit', minute: '2-digit', hour12: false
|
|
20
|
+
}).replace(',', '');
|
|
21
|
+
console.log(`\x1b[38;5;121m[Mint] v${pkg.version} | ${startupTime} | Active Model: ${startupModel}\x1b[0m`);
|
|
22
|
+
|
|
12
23
|
// ANSI Colors
|
|
13
24
|
const colors = {
|
|
14
25
|
reset: "\x1b[0m",
|
|
@@ -23,64 +34,64 @@ const colors = {
|
|
|
23
34
|
const program = new Command();
|
|
24
35
|
|
|
25
36
|
program
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
37
|
+
.name('mint-ai')
|
|
38
|
+
.description('Mint - Your Personal AI Assistant CLI')
|
|
39
|
+
.version(pkg.version);
|
|
29
40
|
|
|
30
41
|
// Chat Command (Interactive Mode)
|
|
31
42
|
program
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
43
|
+
.command('chat', { isDefault: true })
|
|
44
|
+
.description('Start interactive chat session with Mint')
|
|
45
|
+
.argument('[message]', 'Initial message to send to Mint')
|
|
46
|
+
.action(async (message) => {
|
|
47
|
+
await startInteractiveChat(message);
|
|
48
|
+
});
|
|
38
49
|
|
|
39
50
|
// Onboard Command
|
|
40
51
|
program
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
52
|
+
.command('onboard')
|
|
53
|
+
.description('Setup Mint for the first time')
|
|
54
|
+
.option('--install-daemon', 'Automatically install systemd background agent')
|
|
55
|
+
.action(async (options) => {
|
|
56
|
+
await runOnboarding(options);
|
|
57
|
+
});
|
|
47
58
|
|
|
48
59
|
// Agent Command (Headless Daemon Mode)
|
|
49
60
|
program
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
+
.command('agent')
|
|
62
|
+
.description('Run Mint as a background agent (headless)')
|
|
63
|
+
.argument('[initialTask]', 'Optional first task to perform immediately on startup')
|
|
64
|
+
.action(async (initialTask) => {
|
|
65
|
+
if (initialTask) {
|
|
66
|
+
const taskManager = require('./src/System/task_manager');
|
|
67
|
+
taskManager.addTask(initialTask);
|
|
68
|
+
console.log(`\n${colors.mint}${colors.bright}[Mint-Agent] Starting with initial task:${colors.reset} "${initialTask}"`);
|
|
69
|
+
}
|
|
70
|
+
await startAgent();
|
|
71
|
+
});
|
|
61
72
|
|
|
62
73
|
// List Command
|
|
63
74
|
program
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
75
|
+
.command('list')
|
|
76
|
+
.description('Show list of Mint features and commands')
|
|
77
|
+
.action(() => {
|
|
78
|
+
displayFeatures();
|
|
79
|
+
});
|
|
69
80
|
|
|
70
81
|
// Task Command (Autonomous Background Task)
|
|
71
82
|
program
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
83
|
+
.command('task')
|
|
84
|
+
.description('Delegate a complex task to the background agent')
|
|
85
|
+
.argument('<description>', 'Description of the task for Mint to perform autonomously')
|
|
86
|
+
.action(async (description) => {
|
|
87
|
+
const taskManager = require('./src/System/task_manager');
|
|
88
|
+
const task = taskManager.addTask(description);
|
|
89
|
+
console.log(`\n${colors.mint}${colors.bright}Task Received!${colors.reset}`);
|
|
90
|
+
console.log(`${colors.gray}Task ID: ${task.id}${colors.reset}`);
|
|
91
|
+
console.log(`"${description}"`);
|
|
92
|
+
console.log(`\n${colors.cyan}Mint Agent is starting to work on this in the background.${colors.reset}`);
|
|
93
|
+
console.log(`${colors.gray}You will receive a notification when it's done.${colors.reset}\n`);
|
|
94
|
+
});
|
|
84
95
|
|
|
85
96
|
program.parse(process.argv);
|
|
86
97
|
|
|
@@ -92,7 +103,7 @@ async function startInteractiveChat(initialMessage = null) {
|
|
|
92
103
|
onSubmit: async (text) => {
|
|
93
104
|
if (text.startsWith('/')) {
|
|
94
105
|
// Slash commands via fake rl-compatible object
|
|
95
|
-
const fakeRl = { close: () => {} };
|
|
106
|
+
const fakeRl = { close: () => { } };
|
|
96
107
|
appendMessage('user', text);
|
|
97
108
|
await handleSlashCommandUI(text, appendMessage, updateStatusModel, copyLastResponse);
|
|
98
109
|
return;
|
|
@@ -127,6 +138,9 @@ async function startInteractiveChat(initialMessage = null) {
|
|
|
127
138
|
},
|
|
128
139
|
onExit: () => {
|
|
129
140
|
screen.destroy();
|
|
141
|
+
// Explicitly restore terminal state and disable ALL mouse tracking modes
|
|
142
|
+
process.stdout.write('\x1b[?1000l\x1b[?1002l\x1b[?1003l\x1b[?1006l');
|
|
143
|
+
process.stdout.write('\x1b[?25h'); // Show cursor
|
|
130
144
|
console.log(`\n${colors.pink}Goodbye! See you again soon!${colors.reset}\n`);
|
|
131
145
|
process.exit(0);
|
|
132
146
|
}
|
|
@@ -173,6 +187,7 @@ async function handleSlashCommandUI(input, appendMessage, updateStatusModel, cop
|
|
|
173
187
|
].join('\n'));
|
|
174
188
|
break;
|
|
175
189
|
|
|
190
|
+
case '/model':
|
|
176
191
|
case '/models':
|
|
177
192
|
const config = readConfig();
|
|
178
193
|
if (args.length === 0) {
|
|
@@ -204,6 +219,7 @@ async function handleSlashCommandUI(input, appendMessage, updateStatusModel, cop
|
|
|
204
219
|
const currentCfg = readConfig();
|
|
205
220
|
appendMessage('system', [
|
|
206
221
|
'Current Configuration:',
|
|
222
|
+
` Version : v${pkg.version}`,
|
|
207
223
|
` Provider : ${currentCfg.aiProvider}`,
|
|
208
224
|
` Model : ${currentCfg.geminiModel}`,
|
|
209
225
|
` Ollama : ${currentCfg.ollamaModel}`,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pheem49/mint",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.4",
|
|
4
4
|
"description": "A powerful Electron-based AI desktop assistant powered by Google Gemini, featuring screen vision, web automation, and proactive suggestions.",
|
|
5
5
|
"main": "main.js",
|
|
6
6
|
"scripts": {
|
|
@@ -6,7 +6,7 @@ const pluginManager = require('../Plugins/plugin_manager');
|
|
|
6
6
|
let ai = null;
|
|
7
7
|
let activeApiKey = '';
|
|
8
8
|
const initialEnvKey = (process.env.GEMINI_API_KEY || '').trim();
|
|
9
|
-
const DEFAULT_GEMINI_MODEL = 'gemini-2.
|
|
9
|
+
const DEFAULT_GEMINI_MODEL = 'gemini-2.5-flash'; // Optimized model
|
|
10
10
|
|
|
11
11
|
function decodeUnicode(str) {
|
|
12
12
|
if (!str) return '';
|
|
@@ -133,7 +133,7 @@ function createChat(history = []) {
|
|
|
133
133
|
|
|
134
134
|
activeModel = resolveGeminiModel();
|
|
135
135
|
if (activeModel && activeModel !== lastLoggedModel) {
|
|
136
|
-
console.log(`[Gemini] Using model: ${activeModel}`);
|
|
136
|
+
// console.log(`[Gemini] Using model: ${activeModel}`);
|
|
137
137
|
lastLoggedModel = activeModel;
|
|
138
138
|
}
|
|
139
139
|
chat = ai.chats.create({
|
|
@@ -9,7 +9,7 @@ const { readConfig } = require('../System/config_manager');
|
|
|
9
9
|
// ============================================================
|
|
10
10
|
|
|
11
11
|
const ai = new GoogleGenAI({});
|
|
12
|
-
const DEFAULT_GEMINI_MODEL = 'gemini-
|
|
12
|
+
const DEFAULT_GEMINI_MODEL = 'gemini-2.5-flash';
|
|
13
13
|
let lastLoggedModel = '';
|
|
14
14
|
|
|
15
15
|
const PROACTIVE_SYSTEM_PROMPT = `You are a Smart Suggestion Engine built into a Desktop AI Agent called "Mint".
|
|
@@ -3,7 +3,7 @@ const { GoogleGenAI } = require('@google/genai');
|
|
|
3
3
|
const { readConfig } = require('../System/config_manager');
|
|
4
4
|
|
|
5
5
|
const ai = new GoogleGenAI({});
|
|
6
|
-
const DEFAULT_GEMINI_MODEL = 'gemini-
|
|
6
|
+
const DEFAULT_GEMINI_MODEL = 'gemini-2.5-flash';
|
|
7
7
|
let lastLoggedModel = '';
|
|
8
8
|
|
|
9
9
|
const BROWSER_SYSTEM_PROMPT = `You are an Autonomous Browser Agent. Your goal is to fulfill the user's web instruction by driving a headless browser.
|
|
@@ -9,6 +9,44 @@ const fs = require('fs');
|
|
|
9
9
|
const path = require('path');
|
|
10
10
|
const os = require('os');
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Smartly resolves a path.
|
|
14
|
+
* If a path starts with '/' but doesn't exist at root, checks if it exists relative to home.
|
|
15
|
+
* Also handles '~/' expansion.
|
|
16
|
+
*/
|
|
17
|
+
function resolveSmartPath(target) {
|
|
18
|
+
if (!target) return target;
|
|
19
|
+
|
|
20
|
+
// 1. If it exists as is (absolute or relative to CWD), use it
|
|
21
|
+
if (fs.existsSync(target)) return target;
|
|
22
|
+
|
|
23
|
+
const commonFolders = ['Downloads', 'Desktop', 'Documents', 'Videos', 'Pictures', 'Music', 'vscode', 'Games'];
|
|
24
|
+
|
|
25
|
+
// 2. If it starts with / and doesn't exist at root, try home directory
|
|
26
|
+
if (target.startsWith('/')) {
|
|
27
|
+
const homeRelative = path.join(os.homedir(), target.substring(1));
|
|
28
|
+
if (fs.existsSync(homeRelative)) return homeRelative;
|
|
29
|
+
|
|
30
|
+
const cwdRelative = path.join(process.cwd(), target.substring(1));
|
|
31
|
+
if (fs.existsSync(cwdRelative)) return cwdRelative;
|
|
32
|
+
|
|
33
|
+
const firstPart = target.split('/')[1];
|
|
34
|
+
if (commonFolders.includes(firstPart)) return homeRelative;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// 3. Handle ~ manually
|
|
38
|
+
if (target.startsWith('~/')) {
|
|
39
|
+
return path.join(os.homedir(), target.substring(2));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// 4. If it's just a name, search in common folders
|
|
43
|
+
for (const folder of commonFolders) {
|
|
44
|
+
const potentialPath = path.join(os.homedir(), folder, target);
|
|
45
|
+
if (fs.existsSync(potentialPath)) return potentialPath;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return target;
|
|
49
|
+
}
|
|
12
50
|
/**
|
|
13
51
|
* เธชเธฃเนเธฒเธเนเธเธฅเนเธเธญเธฃเนเนเธซเธกเน
|
|
14
52
|
* target: เธเธทเนเธญเนเธเธฅเนเธเธญเธฃเน เธซเธฃเธทเธญ absolute path
|
|
@@ -17,12 +55,12 @@ const os = require('os');
|
|
|
17
55
|
function createFolder(target) {
|
|
18
56
|
if (!target) return { success: false, message: 'No folder name provided.' };
|
|
19
57
|
|
|
20
|
-
let folderPath = target;
|
|
58
|
+
let folderPath = resolveSmartPath(target);
|
|
21
59
|
|
|
22
|
-
//
|
|
23
|
-
if (!path.isAbsolute(
|
|
60
|
+
// If still not absolute (was just a name), default to Desktop
|
|
61
|
+
if (!path.isAbsolute(folderPath)) {
|
|
24
62
|
const desktopPath = path.join(os.homedir(), 'Desktop');
|
|
25
|
-
folderPath = path.join(desktopPath,
|
|
63
|
+
folderPath = path.join(desktopPath, folderPath);
|
|
26
64
|
}
|
|
27
65
|
|
|
28
66
|
try {
|
|
@@ -40,11 +78,13 @@ function createFolder(target) {
|
|
|
40
78
|
*/
|
|
41
79
|
async function openFile(target) {
|
|
42
80
|
if (!target) return;
|
|
81
|
+
const resolvedPath = resolveSmartPath(target);
|
|
82
|
+
|
|
43
83
|
if (shell) {
|
|
44
|
-
const result = await shell.openPath(
|
|
84
|
+
const result = await shell.openPath(resolvedPath);
|
|
45
85
|
if (result) console.error('openFile error:', result);
|
|
46
86
|
} else {
|
|
47
|
-
exec(`xdg-open "${
|
|
87
|
+
exec(`xdg-open "${resolvedPath}"`, (err) => {
|
|
48
88
|
if (err) console.error("Failed to open path via xdg-open:", err);
|
|
49
89
|
});
|
|
50
90
|
}
|
|
@@ -55,9 +95,11 @@ async function openFile(target) {
|
|
|
55
95
|
*/
|
|
56
96
|
async function deleteFile(target) {
|
|
57
97
|
if (!target) return { success: false, message: 'No path provided.' };
|
|
98
|
+
const resolvedPath = resolveSmartPath(target);
|
|
99
|
+
|
|
58
100
|
if (shell) {
|
|
59
101
|
try {
|
|
60
|
-
await shell.trashItem(
|
|
102
|
+
await shell.trashItem(resolvedPath);
|
|
61
103
|
return { success: true };
|
|
62
104
|
} catch (err) {
|
|
63
105
|
console.error('deleteFile error:', err);
|
|
@@ -65,7 +107,7 @@ async function deleteFile(target) {
|
|
|
65
107
|
}
|
|
66
108
|
} else {
|
|
67
109
|
return new Promise((resolve) => {
|
|
68
|
-
exec(`gio trash "${
|
|
110
|
+
exec(`gio trash "${resolvedPath}"`, (err) => {
|
|
69
111
|
if (err) {
|
|
70
112
|
console.error("Failed to trash item via gio trash:", err);
|
|
71
113
|
resolve({ success: false, message: err.message });
|
package/src/CLI/chat_ui.js
CHANGED
|
@@ -35,12 +35,7 @@ function createChatUI({ onSubmit, onExit }) {
|
|
|
35
35
|
smartCSR: true,
|
|
36
36
|
fullUnicode: true,
|
|
37
37
|
title: 'Mint CLI',
|
|
38
|
-
|
|
39
|
-
artificial: true,
|
|
40
|
-
shape: 'line',
|
|
41
|
-
blink: true,
|
|
42
|
-
color: '#88e0b0'
|
|
43
|
-
}
|
|
38
|
+
mouse: true
|
|
44
39
|
});
|
|
45
40
|
|
|
46
41
|
// โโโ Banner โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
@@ -75,7 +70,9 @@ function createChatUI({ onSubmit, onExit }) {
|
|
|
75
70
|
scrollable: true,
|
|
76
71
|
alwaysScroll: true,
|
|
77
72
|
scrollbar: { ch: 'โ', style: { fg: '#334433' } },
|
|
78
|
-
style: { bg: 'default', fg: '#ffffff' }
|
|
73
|
+
style: { bg: 'default', fg: '#ffffff' },
|
|
74
|
+
mouse: true,
|
|
75
|
+
scrollable: true
|
|
79
76
|
});
|
|
80
77
|
|
|
81
78
|
// โโโ Divider above input โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
@@ -89,7 +86,7 @@ function createChatUI({ onSubmit, onExit }) {
|
|
|
89
86
|
const hintBar = blessed.box({
|
|
90
87
|
bottom: 6, left: 0, width: '100%', height: 1,
|
|
91
88
|
tags: true,
|
|
92
|
-
content: `{gray-fg} Shift+
|
|
89
|
+
content: `{gray-fg} Shift+Drag to select text ยท Scroll to view history ยท /help for commands{/}`,
|
|
93
90
|
style: { bg: 'default' }
|
|
94
91
|
});
|
|
95
92
|
|
|
@@ -355,7 +352,7 @@ function createChatUI({ onSubmit, onExit }) {
|
|
|
355
352
|
// Ctrl+C โ double-press to exit
|
|
356
353
|
let ctrlCPressed = false;
|
|
357
354
|
let ctrlCTimer = null;
|
|
358
|
-
const HINT_DEFAULT = `{gray-fg} Ctrl+Y copy
|
|
355
|
+
const HINT_DEFAULT = `{gray-fg} Shift+Drag to select text ยท Ctrl+Y to copy ยท /help for commands{/}`;
|
|
359
356
|
|
|
360
357
|
screen.key(['C-c'], () => {
|
|
361
358
|
if (ctrlCPressed) {
|
|
@@ -431,24 +428,58 @@ function createChatUI({ onSubmit, onExit }) {
|
|
|
431
428
|
* @param {string} timestamp - ISO string or Date object
|
|
432
429
|
*/
|
|
433
430
|
function appendMessage(role, text, timestamp = null) {
|
|
434
|
-
const lines = text.split('\n');
|
|
435
431
|
const now = timestamp ? new Date(timestamp) : new Date();
|
|
436
432
|
const timeStr = now.toLocaleTimeString('th-TH', { hour: '2-digit', minute: '2-digit', hour12: false });
|
|
437
433
|
|
|
434
|
+
// Helper to wrap text manually since blessed.log doesn't support indenting wrapped lines
|
|
435
|
+
const wrapText = (str, width) => {
|
|
436
|
+
const lines = [];
|
|
437
|
+
const originalLines = str.split('\n');
|
|
438
|
+
|
|
439
|
+
for (let line of originalLines) {
|
|
440
|
+
if (line.length === 0) {
|
|
441
|
+
lines.push('');
|
|
442
|
+
continue;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
let current = '';
|
|
446
|
+
for (let i = 0; i < line.length; i++) {
|
|
447
|
+
current += line[i];
|
|
448
|
+
// Simple wrap based on character count.
|
|
449
|
+
// Note: This is an approximation for Thai, but better than terminal auto-wrap.
|
|
450
|
+
if (current.length >= width) {
|
|
451
|
+
lines.push(current);
|
|
452
|
+
current = '';
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
if (current) lines.push(current);
|
|
456
|
+
}
|
|
457
|
+
return lines;
|
|
458
|
+
};
|
|
459
|
+
|
|
460
|
+
const maxLineWidth = Math.max(screen.width - 15, 40);
|
|
461
|
+
|
|
438
462
|
if (role === 'user') {
|
|
439
|
-
chatBox.log(`\n {bold}{#88e0b0-fg}
|
|
440
|
-
lines
|
|
463
|
+
chatBox.log(`\n {bold}{#88e0b0-fg}โ You{/}`);
|
|
464
|
+
const lines = wrapText(text, maxLineWidth);
|
|
465
|
+
lines.forEach(l => chatBox.log(` {#ffffff-fg}${l}{/}`));
|
|
441
466
|
chatBox.log(` {gray-fg}${timeStr}{/}`);
|
|
442
467
|
} else if (role === 'assistant') {
|
|
443
|
-
lastAssistantResponse = text;
|
|
444
|
-
chatBox.log(`\n {bold}{#d4a8ff-fg}Mint
|
|
445
|
-
lines
|
|
446
|
-
chatBox.log(` {
|
|
447
|
-
chatBox.log('');
|
|
468
|
+
lastAssistantResponse = text;
|
|
469
|
+
chatBox.log(`\n {bold}{#d4a8ff-fg}โ Mint{/}`);
|
|
470
|
+
const lines = wrapText(text, maxLineWidth);
|
|
471
|
+
lines.forEach(l => chatBox.log(` {#444444-fg}โ{/} {#ffffff-fg}${l}{/}`));
|
|
472
|
+
chatBox.log(` {#444444-fg}โ${'โ'.repeat(4)}{/} {gray-fg}${timeStr}{/}`);
|
|
448
473
|
} else if (role === 'system') {
|
|
449
|
-
|
|
474
|
+
const displayTag = text.startsWith('Action:') ? '{#88e0b0-fg}โฆ Action:{/}' : '{#888888-fg}โน System:{/}';
|
|
475
|
+
const cleanText = text.replace(/^(Action:|System:)\s*/, '');
|
|
476
|
+
chatBox.log(`\n ${displayTag}`);
|
|
477
|
+
const lines = wrapText(cleanText, maxLineWidth - 2);
|
|
478
|
+
lines.forEach(l => chatBox.log(` {#ffffff-fg}${l}{/}`));
|
|
450
479
|
} else if (role === 'error') {
|
|
451
|
-
chatBox.log(`\n
|
|
480
|
+
chatBox.log(`\n {#ff5555-fg}โ Error:{/}`);
|
|
481
|
+
const lines = wrapText(text, maxLineWidth - 2);
|
|
482
|
+
lines.forEach(l => chatBox.log(` {#ff5555-fg}${l}{/}`));
|
|
452
483
|
}
|
|
453
484
|
screen.render();
|
|
454
485
|
}
|
|
@@ -28,7 +28,7 @@ class PluginManager {
|
|
|
28
28
|
const plugin = require(pluginPath);
|
|
29
29
|
if (this.validatePlugin(plugin)) {
|
|
30
30
|
this.plugins.set(plugin.name, plugin);
|
|
31
|
-
console.log(`[PluginManager] Loaded: ${plugin.name}`);
|
|
31
|
+
// console.log(`[PluginManager] Loaded: ${plugin.name}`);
|
|
32
32
|
} else {
|
|
33
33
|
console.warn(`[PluginManager] Invalid plugin format: ${file}`);
|
|
34
34
|
}
|
|
@@ -67,7 +67,7 @@ class PluginManager {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
try {
|
|
70
|
-
console.log(`[PluginManager] Executing ${name} with instruction: "${instruction}"`);
|
|
70
|
+
// console.log(`[PluginManager] Executing ${name} with instruction: "${instruction}"`);
|
|
71
71
|
return await plugin.execute(instruction);
|
|
72
72
|
} catch (err) {
|
|
73
73
|
console.error(`[PluginManager] Error executing plugin ${name}:`, err);
|
|
@@ -82,6 +82,34 @@ const SystemAutomation = {
|
|
|
82
82
|
} catch (e) {
|
|
83
83
|
throw new Error("xdotool not found. Cannot perform window management.");
|
|
84
84
|
}
|
|
85
|
+
},
|
|
86
|
+
|
|
87
|
+
// System Information
|
|
88
|
+
async getSystemInfo(target = "") {
|
|
89
|
+
// If target is empty, return OS info
|
|
90
|
+
if (!target) {
|
|
91
|
+
try {
|
|
92
|
+
// Try lsb_release first
|
|
93
|
+
const osInfo = await execPromise('lsb_release -ds');
|
|
94
|
+
const kernel = await execPromise('uname -r');
|
|
95
|
+
const arch = await execPromise('uname -m');
|
|
96
|
+
return `Operating System: ${osInfo}\nKernel: ${kernel}\nArchitecture: ${arch}`;
|
|
97
|
+
} catch (e) {
|
|
98
|
+
try {
|
|
99
|
+
// Fallback to /etc/os-release
|
|
100
|
+
const osInfo = await execPromise('grep PRETTY_NAME /etc/os-release | cut -d\'"\' -f2');
|
|
101
|
+
const kernel = await execPromise('uname -r');
|
|
102
|
+
const arch = await execPromise('uname -m');
|
|
103
|
+
return `Operating System: ${osInfo}\nKernel: ${kernel}\nArchitecture: ${arch}`;
|
|
104
|
+
} catch (err) {
|
|
105
|
+
return "Could not retrieve OS information.";
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Handle weather or other info if target is provided
|
|
111
|
+
// For now, let's just return a placeholder or handle it if needed
|
|
112
|
+
return `System info for ${target} is not yet implemented.`;
|
|
85
113
|
}
|
|
86
114
|
};
|
|
87
115
|
|
package/src/UI/settings.js
CHANGED
package/docs/assets/hero-bg.png
DELETED
|
Binary file
|
package/docs/assets/logo.png
DELETED
|
Binary file
|