@umastro12/mino 0.0.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/README.md ADDED
@@ -0,0 +1,71 @@
1
+ # ๐Ÿ’ป Mino โ€” Personal Developer AI Assistent
2
+
3
+ <p align="center">
4
+ <img src="mino_banner.png" alt="Mino" width="300">
5
+ </p>
6
+
7
+ An AI Assistent that help developers directly into the terminal, with the power of **qwen/qwen3-32b** Model. Think of it as your personal AI pair programmer, researcher, and assistant โ€” always ready, always fast.
8
+
9
+ <h2 align=center>๐Ÿ’ธ Support Mino's Project</h2>
10
+ <p align=center>Loves Mino? Support us in <strong>Livepix</strong>, Your support keeps this project alive and growing! This is a 100% free, open-source project developed with countless hours of dedication.</p>
11
+
12
+ <div align=center>
13
+
14
+ **[๐Ÿ‘‰ Click here to support the project](https://livepix.gg/astrooficial)**
15
+
16
+ </div>
17
+
18
+ ## ๐Ÿš€ Installation
19
+
20
+ ### Quick Install
21
+
22
+ ```
23
+ npm install -g openmino
24
+ Or...
25
+ bun add openmino
26
+ ```
27
+
28
+ After installation, the `mino` command is available globally:
29
+
30
+ ```
31
+ mino welcome
32
+ ```
33
+
34
+ ---
35
+
36
+ ## โš™๏ธ Configuration
37
+
38
+ Mino uses **Groq API Key**, you can use your Own qwen3 API Key.
39
+
40
+ ```bash
41
+ # Linux/MacOS
42
+ export AI_API_KEY
43
+
44
+ # Windows
45
+ $env:AI_API_KEY
46
+ ```
47
+
48
+ ## ๐Ÿ’ซ Tools
49
+
50
+ Mino can:
51
+
52
+ - write project structure files
53
+ - run commands
54
+ - search the web
55
+
56
+ ## ๐Ÿ› ๏ธ CLI Commands
57
+
58
+ ```bash
59
+ mino welcome # - Show Mino's Welcome Panel
60
+
61
+ mino help # - Show Help(Alias: -h, --help)
62
+
63
+ mino ask # - Ask a Quick Question with qwen/qwen3-32b Model
64
+
65
+ mino update install # - Install a avaialable update
66
+ ```
67
+
68
+ ---
69
+
70
+ <h3 align=center>Developed with โค๏ธ by OpenMino and Astro</h3>
71
+ <p align=center><strong>Version 0.0.1 ยท 20+ Tests passing ยท 1 AI Model</strong></p>
package/bun.lock ADDED
@@ -0,0 +1,194 @@
1
+ {
2
+ "lockfileVersion": 1,
3
+ "configVersion": 1,
4
+ "workspaces": {
5
+ "": {
6
+ "dependencies": {
7
+ "@types/node": "^25.8.0",
8
+ "boxen": "^8.0.1",
9
+ "chalk": "^5.6.2",
10
+ "commander": "^14.0.3",
11
+ "fs": "^0.0.1-security",
12
+ "groq-sdk": "^1.2.0",
13
+ "marked": "^18.0.3",
14
+ "marked-terminal": "^7.3.0",
15
+ "ora": "^9.4.0",
16
+ },
17
+ },
18
+ },
19
+ "packages": {
20
+ "@colors/colors": ["@colors/colors@1.5.0", "", {}, "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ=="],
21
+
22
+ "@sindresorhus/is": ["@sindresorhus/is@4.6.0", "", {}, "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw=="],
23
+
24
+ "@types/node": ["@types/node@25.8.0", "", { "dependencies": { "undici-types": ">=7.24.0 <7.24.7" } }, "sha512-TCFSk8IZh+iLX1xtksoBVtdmgL+1IX0fC9BeU4QqFSuNdN/K+HUlhqOzEmSYYpZUVsLYcPqc9KX+60iDuninSQ=="],
25
+
26
+ "ansi-align": ["ansi-align@3.0.1", "", { "dependencies": { "string-width": "^4.1.0" } }, "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w=="],
27
+
28
+ "ansi-escapes": ["ansi-escapes@7.3.0", "", { "dependencies": { "environment": "^1.0.0" } }, "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg=="],
29
+
30
+ "ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="],
31
+
32
+ "ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="],
33
+
34
+ "any-promise": ["any-promise@1.3.0", "", {}, "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="],
35
+
36
+ "boxen": ["boxen@8.0.1", "", { "dependencies": { "ansi-align": "^3.0.1", "camelcase": "^8.0.0", "chalk": "^5.3.0", "cli-boxes": "^3.0.0", "string-width": "^7.2.0", "type-fest": "^4.21.0", "widest-line": "^5.0.0", "wrap-ansi": "^9.0.0" } }, "sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw=="],
37
+
38
+ "camelcase": ["camelcase@8.0.0", "", {}, "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA=="],
39
+
40
+ "chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="],
41
+
42
+ "char-regex": ["char-regex@1.0.2", "", {}, "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw=="],
43
+
44
+ "cli-boxes": ["cli-boxes@3.0.0", "", {}, "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g=="],
45
+
46
+ "cli-cursor": ["cli-cursor@5.0.0", "", { "dependencies": { "restore-cursor": "^5.0.0" } }, "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw=="],
47
+
48
+ "cli-highlight": ["cli-highlight@2.1.11", "", { "dependencies": { "chalk": "^4.0.0", "highlight.js": "^10.7.1", "mz": "^2.4.0", "parse5": "^5.1.1", "parse5-htmlparser2-tree-adapter": "^6.0.0", "yargs": "^16.0.0" }, "bin": { "highlight": "bin/highlight" } }, "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg=="],
49
+
50
+ "cli-spinners": ["cli-spinners@3.4.0", "", {}, "sha512-bXfOC4QcT1tKXGorxL3wbJm6XJPDqEnij2gQ2m7ESQuE+/z9YFIWnl/5RpTiKWbMq3EVKR4fRLJGn6DVfu0mpw=="],
51
+
52
+ "cli-table3": ["cli-table3@0.6.5", "", { "dependencies": { "string-width": "^4.2.0" }, "optionalDependencies": { "@colors/colors": "1.5.0" } }, "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ=="],
53
+
54
+ "cliui": ["cliui@7.0.4", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" } }, "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ=="],
55
+
56
+ "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
57
+
58
+ "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
59
+
60
+ "commander": ["commander@14.0.3", "", {}, "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw=="],
61
+
62
+ "emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="],
63
+
64
+ "emojilib": ["emojilib@2.4.0", "", {}, "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw=="],
65
+
66
+ "environment": ["environment@1.1.0", "", {}, "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q=="],
67
+
68
+ "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="],
69
+
70
+ "fs": ["fs@0.0.1-security", "", {}, "sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w=="],
71
+
72
+ "get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="],
73
+
74
+ "get-east-asian-width": ["get-east-asian-width@1.6.0", "", {}, "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA=="],
75
+
76
+ "groq-sdk": ["groq-sdk@1.2.0", "", { "bin": { "groq-sdk": "bin/cli" } }, "sha512-pMhSYXWcjiqvbOeKdv2zjci1BYjGdp04a40hnmQmJpKJyB6oa+gRndAqE128gwR0NLgYO+Wt1fIF46KNHcplsw=="],
77
+
78
+ "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
79
+
80
+ "highlight.js": ["highlight.js@10.7.3", "", {}, "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A=="],
81
+
82
+ "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="],
83
+
84
+ "is-interactive": ["is-interactive@2.0.0", "", {}, "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ=="],
85
+
86
+ "is-unicode-supported": ["is-unicode-supported@2.1.0", "", {}, "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ=="],
87
+
88
+ "log-symbols": ["log-symbols@7.0.1", "", { "dependencies": { "is-unicode-supported": "^2.0.0", "yoctocolors": "^2.1.1" } }, "sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg=="],
89
+
90
+ "marked": ["marked@18.0.3", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-7VT90JOkDeaRWpfjOReRGPEKn0ecdARBkDGL+tT1wZY0efPPqkUxLUSmzy/C7TIylQYJC9STISEsCHrqb/7VIA=="],
91
+
92
+ "marked-terminal": ["marked-terminal@7.3.0", "", { "dependencies": { "ansi-escapes": "^7.0.0", "ansi-regex": "^6.1.0", "chalk": "^5.4.1", "cli-highlight": "^2.1.11", "cli-table3": "^0.6.5", "node-emoji": "^2.2.0", "supports-hyperlinks": "^3.1.0" }, "peerDependencies": { "marked": ">=1 <16" } }, "sha512-t4rBvPsHc57uE/2nJOLmMbZCQ4tgAccAED3ngXQqW6g+TxA488JzJ+FK3lQkzBQOI1mRV/r/Kq+1ZlJ4D0owQw=="],
93
+
94
+ "mimic-function": ["mimic-function@5.0.1", "", {}, "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA=="],
95
+
96
+ "mz": ["mz@2.7.0", "", { "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", "thenify-all": "^1.0.0" } }, "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q=="],
97
+
98
+ "node-emoji": ["node-emoji@2.2.0", "", { "dependencies": { "@sindresorhus/is": "^4.6.0", "char-regex": "^1.0.2", "emojilib": "^2.4.0", "skin-tone": "^2.0.0" } }, "sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw=="],
99
+
100
+ "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="],
101
+
102
+ "onetime": ["onetime@7.0.0", "", { "dependencies": { "mimic-function": "^5.0.0" } }, "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ=="],
103
+
104
+ "ora": ["ora@9.4.0", "", { "dependencies": { "chalk": "^5.6.2", "cli-cursor": "^5.0.0", "cli-spinners": "^3.2.0", "is-interactive": "^2.0.0", "is-unicode-supported": "^2.1.0", "log-symbols": "^7.0.1", "stdin-discarder": "^0.3.2", "string-width": "^8.1.0" } }, "sha512-84cglkRILFxdtA8hAvLNdMrtBpPNBTrQ9/ulg0FA7xLMnD6mifv+enAIeRmvtv+WgdCE+LPGOfQmtJRrVaIVhQ=="],
105
+
106
+ "parse5": ["parse5@5.1.1", "", {}, "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug=="],
107
+
108
+ "parse5-htmlparser2-tree-adapter": ["parse5-htmlparser2-tree-adapter@6.0.1", "", { "dependencies": { "parse5": "^6.0.1" } }, "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA=="],
109
+
110
+ "require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="],
111
+
112
+ "restore-cursor": ["restore-cursor@5.1.0", "", { "dependencies": { "onetime": "^7.0.0", "signal-exit": "^4.1.0" } }, "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA=="],
113
+
114
+ "signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="],
115
+
116
+ "skin-tone": ["skin-tone@2.0.0", "", { "dependencies": { "unicode-emoji-modifier-base": "^1.0.0" } }, "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA=="],
117
+
118
+ "stdin-discarder": ["stdin-discarder@0.3.2", "", {}, "sha512-eCPu1qRxPVkl5605OTWF8Wz40b4Mf45NY5LQmVPQ599knfs5QhASUm9GbJ5BDMDOXgrnh0wyEdvzmL//YMlw0A=="],
119
+
120
+ "string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="],
121
+
122
+ "strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "^6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="],
123
+
124
+ "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
125
+
126
+ "supports-hyperlinks": ["supports-hyperlinks@3.2.0", "", { "dependencies": { "has-flag": "^4.0.0", "supports-color": "^7.0.0" } }, "sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig=="],
127
+
128
+ "thenify": ["thenify@3.3.1", "", { "dependencies": { "any-promise": "^1.0.0" } }, "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw=="],
129
+
130
+ "thenify-all": ["thenify-all@1.6.0", "", { "dependencies": { "thenify": ">= 3.1.0 < 4" } }, "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA=="],
131
+
132
+ "type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="],
133
+
134
+ "undici-types": ["undici-types@7.24.6", "", {}, "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg=="],
135
+
136
+ "unicode-emoji-modifier-base": ["unicode-emoji-modifier-base@1.0.0", "", {}, "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g=="],
137
+
138
+ "widest-line": ["widest-line@5.0.0", "", { "dependencies": { "string-width": "^7.0.0" } }, "sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA=="],
139
+
140
+ "wrap-ansi": ["wrap-ansi@9.0.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww=="],
141
+
142
+ "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="],
143
+
144
+ "yargs": ["yargs@16.2.0", "", { "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.0", "y18n": "^5.0.5", "yargs-parser": "^20.2.2" } }, "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw=="],
145
+
146
+ "yargs-parser": ["yargs-parser@20.2.9", "", {}, "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w=="],
147
+
148
+ "yoctocolors": ["yoctocolors@2.1.2", "", {}, "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug=="],
149
+
150
+ "ansi-align/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
151
+
152
+ "cli-highlight/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
153
+
154
+ "cli-table3/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
155
+
156
+ "cliui/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
157
+
158
+ "cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
159
+
160
+ "cliui/wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
161
+
162
+ "ora/string-width": ["string-width@8.2.1", "", { "dependencies": { "get-east-asian-width": "^1.5.0", "strip-ansi": "^7.1.2" } }, "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA=="],
163
+
164
+ "parse5-htmlparser2-tree-adapter/parse5": ["parse5@6.0.1", "", {}, "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw=="],
165
+
166
+ "yargs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
167
+
168
+ "ansi-align/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
169
+
170
+ "ansi-align/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
171
+
172
+ "cli-highlight/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
173
+
174
+ "cli-table3/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
175
+
176
+ "cli-table3/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
177
+
178
+ "cliui/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
179
+
180
+ "cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
181
+
182
+ "cliui/wrap-ansi/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
183
+
184
+ "yargs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
185
+
186
+ "yargs/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
187
+
188
+ "ansi-align/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
189
+
190
+ "cli-table3/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
191
+
192
+ "yargs/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
193
+ }
194
+ }
Binary file
package/mino_oc.png ADDED
Binary file
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@umastro12/mino",
3
+ "version": "0.0.1",
4
+ "description": "An AI Assistant that help developers directly into the terminal",
5
+ "main": "dist/index.ts",
6
+ "keywords": [
7
+ "ai",
8
+ "cli",
9
+ "chatbot",
10
+ "qwen3",
11
+ "llm",
12
+ "ai-agents",
13
+ "assistant",
14
+ "mino"
15
+ ],
16
+ "author": "umastro12",
17
+ "license": "MIT",
18
+ "engines": {
19
+ "node": ">=20.0.0"
20
+ },
21
+ "dependencies": {
22
+ "@types/node": "^25.8.0",
23
+ "boxen": "^8.0.1",
24
+ "chalk": "^5.6.2",
25
+ "commander": "^14.0.3",
26
+ "fs": "^0.0.1-security",
27
+ "groq-sdk": "^1.2.0",
28
+ "marked": "^18.0.3",
29
+ "marked-terminal": "^7.3.0",
30
+ "ora": "^9.4.0"
31
+ }
32
+ }
@@ -0,0 +1,45 @@
1
+ import { Command } from "commander";
2
+ import { APIClient } from "../services/APIClient.js";
3
+
4
+ async function showPanel() {
5
+ const panel = `
6
+ __ __ _____ _ _ ____
7
+ | \/ ||_ _|| \ | | / __ \
8
+ | \ / | | | | \| | | | | |
9
+ | |\/| | | | | . \`| | | | |
10
+ | | | | _| |_ | |\ | | |__| |
11
+ |_| |_||_____||_| \_| \____/
12
+
13
+ -------------------------------
14
+ Model: qwen/qwen3-32b
15
+ `;
16
+
17
+ console.log(`\x1b[36m${panel}\x1b[0m`);
18
+ }
19
+
20
+ const program = new Command();
21
+
22
+ program
23
+ .name("mino")
24
+ .description("Mino - Personal Developer AI Assistant")
25
+ .helpOption("-h", "--help");
26
+
27
+ program
28
+ .command("ask")
29
+ .alias("-a")
30
+ .description("Ask a quick question without starting a chat session")
31
+ .argument("<question>", "The question to ask")
32
+ .action(async (question) => {
33
+ const apiClient = new APIClient(process.env.AI_API_KEY!, "qwen/qwen3-32b");
34
+ console.log(`You asked: ${question}`);
35
+ });
36
+
37
+ program
38
+ .command("welcome")
39
+ .alias("-w")
40
+ .description("Show Welcome Panel")
41
+ .action(async () => {
42
+ await showPanel();
43
+ });
44
+
45
+ program.parse(process.argv);
@@ -0,0 +1,10 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "ES2020",
5
+ "types": ["node"],
6
+ "esModuleInterop": true,
7
+ "skipLibCheck": true,
8
+ "moduleResolution": "node"
9
+ }
10
+ }
@@ -0,0 +1,25 @@
1
+ import chalk from "chalk";
2
+ import { Spinner } from "../ui/spinner.js";
3
+ import { APIClient } from "../services/APIClient.js";
4
+ import { systemPrompt } from "../prompts/systemPrompt.js";
5
+ import * as executor from "../executor.js";
6
+
7
+ export class AskCommand {
8
+ private apiClient: APIClient;
9
+ private sysPrompt: typeof systemPrompt;
10
+
11
+ constructor(apiClient: APIClient) {
12
+ this.apiClient = apiClient;
13
+ this.sysPrompt = systemPrompt;
14
+ }
15
+
16
+ async startAskCommand(question: string) {
17
+ const messages = [
18
+ { role: "system", content: this.sysPrompt },
19
+ { role: "user", content: question },
20
+ ];
21
+
22
+ const spinner = new Spinner();
23
+ spinner.start("Thinking...");
24
+ }
25
+ }
@@ -0,0 +1,64 @@
1
+ import chalk from "chalk";
2
+
3
+ export interface tokenLimitInfo {
4
+ modelId: string;
5
+ maxTokens: number;
6
+ currentTokens: number;
7
+ usagePercentage: number;
8
+ }
9
+
10
+ export function isTokenLimitApproaching(
11
+ currentTokens: number,
12
+ maxTokens: number,
13
+ threshold: number = 0.8,
14
+ ): boolean {
15
+ return currentTokens >= maxTokens * threshold;
16
+ }
17
+
18
+ export function isTokenLimitExceeded(
19
+ currentTokens: number,
20
+ maxTokens: number,
21
+ ): boolean {
22
+ return currentTokens >= maxTokens;
23
+ }
24
+
25
+ export function getTokenLimitInfo(
26
+ modelId: string,
27
+ maxTokens: number,
28
+ currentTokens: number,
29
+ ): tokenLimitInfo {
30
+ return {
31
+ modelId,
32
+ maxTokens,
33
+ currentTokens,
34
+ usagePercentage: Math.round((currentTokens / maxTokens) * 100),
35
+ };
36
+ }
37
+
38
+ export function showTokenLimitError(info: tokenLimitInfo) {
39
+ const error = [
40
+ `๐Ÿšซ Token limit exceeded`,
41
+ `Model: ${info.modelId}`,
42
+ `Usage: ${info.currentTokens.toLocaleString()} / ${info.maxTokens.toLocaleString()} (100%)`,
43
+ ``,
44
+ `The model has reached its token limit. To continue:`,
45
+ `2. Restart the CLI to start a fresh session`,
46
+ `3. Or switch to a model with higher token limits`,
47
+ ];
48
+ return error.join("\n");
49
+ }
50
+
51
+ /**
52
+ * Create a visual progress bar
53
+ */
54
+ function createProgressBar(percentage: number, width: number): string {
55
+ const filled = Math.round((percentage / 100) * width);
56
+ const empty = width - filled;
57
+
58
+ const color =
59
+ percentage < 50 ? chalk.green : percentage < 80 ? chalk.yellow : chalk.red;
60
+ const filledChar = "โ–ˆ";
61
+ const emptyChar = "โ–‘";
62
+
63
+ return color(filledChar.repeat(filled) + emptyChar.repeat(empty));
64
+ }
@@ -0,0 +1,139 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { spawn } from "child_process";
4
+
5
+ export interface ProjectFile {
6
+ path: string;
7
+ content: string;
8
+ executable?: boolean;
9
+ }
10
+
11
+ export interface RunCommandOptions {
12
+ cwd?: string;
13
+ env?: NodeJS.ProcessEnv;
14
+ timeoutMs?: number;
15
+ captureOutput?: boolean;
16
+ }
17
+
18
+ export interface RunCommandResult {
19
+ stdout: string;
20
+ stderr: string;
21
+ exitCode: number | null;
22
+ }
23
+
24
+ export interface SearchOptions {
25
+ engine?: "google" | "bing" | "duckduckgo";
26
+ }
27
+
28
+ function ensureDirectoryForFile(filePath: string) {
29
+ const dir = path.dirname(filePath);
30
+ if (!fs.existsSync(dir)) {
31
+ fs.mkdirSync(dir, { recursive: true });
32
+ }
33
+ }
34
+
35
+ export async function writeProjectFiles(
36
+ files: ProjectFile[],
37
+ rootDir: string = process.cwd(),
38
+ ): Promise<void> {
39
+ await Promise.all(
40
+ files.map(async (file) => {
41
+ const absolutePath = path.resolve(rootDir, file.path);
42
+ ensureDirectoryForFile(absolutePath);
43
+ await fs.promises.writeFile(absolutePath, file.content, "utf8");
44
+
45
+ if (file.executable && process.platform !== "win32") {
46
+ await fs.promises.chmod(absolutePath, 0o755);
47
+ }
48
+ }),
49
+ );
50
+ }
51
+
52
+ export function runCommand(
53
+ command: string,
54
+ options: RunCommandOptions = {},
55
+ ): Promise<RunCommandResult> {
56
+ return new Promise((resolve, reject) => {
57
+ const stdoutChunks: string[] = [];
58
+ const stderrChunks: string[] = [];
59
+ const proc = spawn(command, {
60
+ cwd: options.cwd ?? process.cwd(),
61
+ env: { ...process.env, ...options.env },
62
+ shell: true,
63
+ });
64
+
65
+ proc.stdout.on("data", (data: Buffer) => {
66
+ const chunk = data.toString();
67
+ stdoutChunks.push(chunk);
68
+ if (options.captureOutput !== false) {
69
+ process.stdout.write(chunk);
70
+ }
71
+ });
72
+
73
+ proc.stderr.on("data", (data: Buffer) => {
74
+ const chunk = data.toString();
75
+ stderrChunks.push(chunk);
76
+ if (options.captureOutput !== false) {
77
+ process.stderr.write(chunk);
78
+ }
79
+ });
80
+
81
+ if (typeof options.timeoutMs === "number") {
82
+ setTimeout(() => {
83
+ proc.kill("SIGTERM");
84
+ }, options.timeoutMs);
85
+ }
86
+
87
+ proc.on("close", (code: number | null) => {
88
+ resolve({
89
+ stdout: stdoutChunks.join(""),
90
+ stderr: stderrChunks.join(""),
91
+ exitCode: code,
92
+ });
93
+ });
94
+
95
+ proc.on("error", (error: Error) => {
96
+ reject(error);
97
+ });
98
+ });
99
+ }
100
+
101
+ export function buildSearchUrl(
102
+ query: string,
103
+ engine: "google" | "bing" | "duckduckgo" = "google",
104
+ ): string {
105
+ const encoded = encodeURIComponent(query);
106
+
107
+ switch (engine) {
108
+ case "bing":
109
+ return `https://www.bing.com/search?q=${encoded}`;
110
+ case "duckduckgo":
111
+ return `https://duckduckgo.com/?q=${encoded}`;
112
+ default:
113
+ return `https://www.google.com/search?q=${encoded}`;
114
+ }
115
+ }
116
+
117
+ export async function searchWeb(
118
+ query: string,
119
+ options: SearchOptions = {},
120
+ ): Promise<string> {
121
+ const url = buildSearchUrl(query, options.engine ?? "google");
122
+ await openUrl(url);
123
+ return url;
124
+ }
125
+
126
+ export async function openUrl(url: string): Promise<void> {
127
+ const safeUrl = url.replace(/"/g, '\\"');
128
+ let command = "";
129
+
130
+ if (process.platform === "win32") {
131
+ command = `start "" "${safeUrl}"`;
132
+ } else if (process.platform === "darwin") {
133
+ command = `open "${safeUrl}"`;
134
+ } else {
135
+ command = `xdg-open "${safeUrl}"`;
136
+ }
137
+
138
+ await runCommand(command, { captureOutput: true });
139
+ }
package/src/index.ts ADDED
@@ -0,0 +1,29 @@
1
+ import Groq from "groq-sdk";
2
+
3
+ const groq = new Groq({
4
+ apiKey: process.env.AI_API_KEY,
5
+ });
6
+
7
+ export async function chatCompletion() {
8
+ const chatCompletion = await groq.chat.completions.create({
9
+ messages: [
10
+ {
11
+ role: "user",
12
+ content: "",
13
+ },
14
+ ],
15
+ model: "qwen/qwen3-32b",
16
+ temperature: 0.6,
17
+ max_completion_tokens: 4096,
18
+ top_p: 0.95,
19
+ stream: true,
20
+ reasoning_effort: "default",
21
+ stop: null,
22
+ });
23
+
24
+ for await (const chunk of chatCompletion) {
25
+ process.stdout.write(chunk.choices[0]?.delta?.content || "");
26
+ }
27
+ }
28
+
29
+ export const chatComplet = chatCompletion();
@@ -0,0 +1,26 @@
1
+ export const systemPrompt = `# Mino - Personal Developer AI Assistant
2
+ # Mino - Personal Developer AI Assistant
3
+
4
+ ## IDENTITY
5
+ You are Mino, a personal AI assistant for developers working in the terminal. Be professional, precise, results-oriented, and helpful.
6
+
7
+ ## TOOLS
8
+ You have three tools:
9
+ - write project structure files
10
+ - run commands
11
+ - search the web
12
+
13
+ ## BEHAVIOR
14
+ - Always prefer concise, actionable answers.
15
+ - When the user asks for code or files, explain the structure and provide exact file content.
16
+ - Only perform file writes or command execution when explicitly requested.
17
+ - When searching the web, return relevant links and short summaries.
18
+
19
+ ## CRITICAL RULES
20
+ 1. BE PROACTIVE: offer useful follow-up suggestions and next steps.
21
+ 2. DO NOT MODIFY FILES UNLESS THE USER ASKS YOU TO.
22
+ 3. If the user asks to create a bot or implement a feature, explain the design and provide a clear example.
23
+ 4. If the user asks for docs or language references, explain the topic and share relevant documentation links.
24
+
25
+
26
+ `;
@@ -0,0 +1,24 @@
1
+ import chalk from "chalk";
2
+ import fs from "fs";
3
+
4
+ export class APIClient {
5
+ private apiKey: string;
6
+ private model: "qwen/qwen3-32b";
7
+
8
+ constructor(apiKey: string, model: "qwen/qwen3-32b") {
9
+ this.apiKey = apiKey;
10
+ this.model = model;
11
+ }
12
+
13
+ setup() {
14
+ console.log(`๐Ÿ’ป Starting API Client Setup...`);
15
+ const APIKey = prompt(`๐Ÿ”‘ Put your API Key here:`);
16
+ if (!APIKey) {
17
+ throw new Error("An API key was not provided.");
18
+ }
19
+ if (APIKey) {
20
+ fs.writeFileSync(".env", `AI_API_KEY=${APIKey}`);
21
+ console.log(`๐Ÿ’ป Setup complete.`);
22
+ }
23
+ }
24
+ }
@@ -0,0 +1,60 @@
1
+ import chalk from "chalk";
2
+ import boxen from "boxen";
3
+
4
+ export interface UpdateInfo {
5
+ updateAvaiable: boolean;
6
+ updateName: string;
7
+ latest?: string | undefined;
8
+ current?: string | undefined;
9
+ publishedAt?: string | undefined;
10
+ }
11
+ export class UpdaterService {
12
+ private packageName: string;
13
+ private currentVersion: string;
14
+
15
+ constructor() {
16
+ this.currentVersion = process.env.APP_VERSION || "0.0.1";
17
+ this.packageName = process.env.APP_NAME || "mino";
18
+ }
19
+
20
+ createUpdateNotification(
21
+ latest: string,
22
+ current: string,
23
+ publishedAt?: string,
24
+ ) {
25
+ const dateInfo = publishedAt
26
+ ? `\n${chalk.dim("Published:")} ${chalk.dim(new Date(publishedAt).toLocaleDateString())}`
27
+ : "";
28
+
29
+ const message = [
30
+ chalk.cyan.bold(`๐Ÿ’ซ Update Available!`),
31
+ "",
32
+ `Current: ${chalk.red(current)}`,
33
+ `Latest: ${chalk.green(latest)}${dateInfo}`,
34
+ "",
35
+ chalk.dim("Run ") +
36
+ chalk.cyan.bold("mino update install") +
37
+ chalk.dim(" to update"),
38
+ chalk.dim("Or: ") + chalk.cyan(`npm update -g ${this.packageName}`),
39
+ ].join("\n");
40
+
41
+ return boxen(message, {
42
+ padding: 1,
43
+ borderColor: "cyan",
44
+ title: ` ${this.packageName} `,
45
+ titleAlignment: "center",
46
+ });
47
+ }
48
+
49
+ showUpdateNotification(
50
+ latest: string,
51
+ current: string,
52
+ publishedAt?: string,
53
+ ): void {
54
+ console.log("");
55
+ console.log(this.createUpdateNotification(latest, current, publishedAt));
56
+ console.log("");
57
+ }
58
+ }
59
+
60
+ export const updaterService = new UpdaterService();
@@ -0,0 +1,7 @@
1
+ {
2
+ "compilerOptions": {
3
+ "types": ["node"],
4
+ "moduleResolution": "node",
5
+ "esModuleInterop": true
6
+ }
7
+ }
@@ -0,0 +1,35 @@
1
+ import chalk from "chalk";
2
+ import { marked } from "marked";
3
+
4
+ const mdRender = {
5
+ code: chalk.hex("#8afdda"),
6
+
7
+ heading: chalk.bold.hex("#0033ff"),
8
+ strong: chalk.bold.white,
9
+ em: chalk.italic.hex("#67E8F9"),
10
+ del: chalk.strikethrough.gray,
11
+
12
+ listitem: chalk.white,
13
+ checkbox: chalk.hex("#0296ff"),
14
+
15
+ blockquote: chalk.gray.italic,
16
+ table: chalk.hex("#00eaff"),
17
+ };
18
+
19
+ export function renderMarkdown(content: string): string {
20
+ if (!content || typeof content !== "string") {
21
+ return "";
22
+ }
23
+
24
+ try {
25
+ const rendered = marked.parse(content);
26
+
27
+ if (typeof rendered !== "string") {
28
+ return content;
29
+ }
30
+
31
+ return rendered;
32
+ } catch (error) {
33
+ return content;
34
+ }
35
+ }
@@ -0,0 +1,36 @@
1
+ // this is based in the https://github.com/shindozk/luxyie.ai-cli/blob/main/src/ui/spinner.ts code.
2
+
3
+ import chalk from "chalk";
4
+ import ora, { Ora } from "ora";
5
+
6
+ export class Spinner {
7
+ private spinner: Ora | null = null;
8
+
9
+ start(text: string): void {
10
+ if (this.spinner) {
11
+ this.spinner.text = text;
12
+ this.spinner.start();
13
+ } else {
14
+ this.spinner = ora({
15
+ text: text,
16
+ color: "cyan",
17
+ spinner: "dots",
18
+ }).start();
19
+ }
20
+ }
21
+
22
+ stop(): void {
23
+ if (this.spinner) {
24
+ this.spinner.stop();
25
+ this.spinner = null;
26
+ }
27
+ }
28
+
29
+ fail(text: string) {
30
+ if (this.spinner) {
31
+ this.spinner.fail(chalk.red(text));
32
+ }
33
+ }
34
+ }
35
+
36
+ export const spinner = new Spinner();
package/tsconfig.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "ES2020",
5
+ "moduleResolution": "node",
6
+ "esModuleInterop": true,
7
+ "forceConsistentCasingInFileNames": true,
8
+ "strict": true,
9
+ "skipLibCheck": true,
10
+ "types": ["node"],
11
+ "resolveJsonModule": true
12
+ },
13
+ "include": ["src/**/*"],
14
+ "exclude": ["node_modules"]
15
+ }