@pheem49/mint 1.6.2 → 1.6.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/.github/workflows/ci.yml +14 -0
- package/Cargo.lock +3 -3
- package/Cargo.toml +1 -1
- package/README.md +82 -21
- package/assets/Mint_CLI.png +0 -0
- package/assets/Mint_Desktop.png +0 -0
- package/assets/Mint_Web.png +0 -0
- package/assets/Mint_WorkSpace.png +0 -0
- package/assets/Setting.png +0 -0
- package/assets/bridges.svg +4 -0
- package/assets/chat.svg +3 -0
- package/assets/code.svg +4 -0
- package/assets/features.svg +3 -0
- package/assets/imagegen.svg +5 -0
- package/assets/live2d.svg +6 -0
- package/assets/memory.svg +5 -0
- package/assets/screencapture.svg +4 -0
- package/assets/setup.svg +3 -0
- package/assets/tools.svg +4 -0
- package/bin/mint +0 -0
- package/crates/mint-cli/src/agent.rs +6 -2
- package/crates/mint-cli/src/main.rs +145 -5
- package/crates/mint-cli/src/onboard.rs +134 -1
- package/crates/mint-core/src/api_server.rs +108 -3
- package/crates/mint-core/src/config.rs +20 -1
- package/crates/mint-core/src/image_gen.rs +895 -0
- package/crates/mint-core/src/lib.rs +4 -0
- package/package.json +3 -3
- package/src/bin/index.js +0 -0
- package/src/renderer/index-web.html +1 -1
- package/src/renderer/index.html +1 -1
- package/src/renderer/src/components/ChatPanel.tsx +252 -26
- package/src/renderer/src/components/DashboardSidebar.tsx +11 -3
- package/src/renderer/src/components/ImageStudioPanel.tsx +638 -0
- package/src/renderer/src/components/MintDashboard.tsx +14 -5
- package/src/renderer/src/components/SettingsWindow.tsx +29 -20
- package/src/renderer/src/css/image-studio.css +722 -0
- package/src/renderer/src/css/settings.css +13 -3
- package/src/renderer/src/css/styles.css +50 -26
- package/src/renderer/src/index.css +106 -0
- package/src/renderer/src/tauri.ts +123 -0
- package/src/renderer/src-web/components/ChatPanel.tsx +273 -25
- package/src/renderer/src-web/components/DashboardSidebar.tsx +11 -3
- package/src/renderer/src-web/components/ImageStudioPanel.tsx +638 -0
- package/src/renderer/src-web/components/MintDashboard.tsx +13 -4
- package/src/renderer/src-web/components/SettingsWindow.tsx +29 -20
- package/src/renderer/src-web/css/image-studio.css +722 -0
- package/src/renderer/src-web/css/settings.css +14 -4
- package/src/renderer/src-web/css/styles.css +50 -26
- package/src/renderer/src-web/index.css +106 -0
- package/src/renderer/src-web/tauri.ts +124 -0
- package/src-tauri/Cargo.toml +29 -0
- package/src-tauri/build.rs +3 -0
- package/src-tauri/capabilities/main.json +7 -0
- package/src-tauri/gen/schemas/acl-manifests.json +1 -0
- package/src-tauri/gen/schemas/capabilities.json +1 -0
- package/src-tauri/gen/schemas/desktop-schema.json +2412 -0
- package/src-tauri/gen/schemas/linux-schema.json +2412 -0
- package/src-tauri/src/browser.rs +141 -0
- package/src-tauri/src/desktop.rs +392 -0
- package/src-tauri/src/discord_rpc.rs +99 -0
- package/src-tauri/src/events.rs +70 -0
- package/src-tauri/src/headless.rs +222 -0
- package/src-tauri/src/integrations.rs +126 -0
- package/src-tauri/src/lib.rs +1076 -0
- package/src-tauri/src/main.rs +3 -0
- package/src-tauri/src/plugins.rs +16 -0
- package/src-tauri/src/proactive.rs +254 -0
- package/src-tauri/src/system.rs +250 -0
- package/src-tauri/src/updater.rs +148 -0
- package/src-tauri/src/webhooks.rs +255 -0
- package/src-tauri/src/workflows.rs +70 -0
- package/src-tauri/tauri.conf.json +48 -0
- package/tsconfig.json +1 -1
package/.github/workflows/ci.yml
CHANGED
|
@@ -23,6 +23,20 @@ jobs:
|
|
|
23
23
|
node-version: 22
|
|
24
24
|
cache: npm
|
|
25
25
|
|
|
26
|
+
- name: Set up Rust
|
|
27
|
+
run: |
|
|
28
|
+
rustup update stable
|
|
29
|
+
rustup default stable
|
|
30
|
+
|
|
31
|
+
- name: Install Tauri Linux dependencies
|
|
32
|
+
run: |
|
|
33
|
+
sudo apt-get update
|
|
34
|
+
sudo apt-get install -y \
|
|
35
|
+
build-essential curl file pkg-config wget \
|
|
36
|
+
libdbus-1-dev libwebkit2gtk-4.1-dev \
|
|
37
|
+
libayatana-appindicator3-dev librsvg2-dev \
|
|
38
|
+
poppler-utils unzip patchelf
|
|
39
|
+
|
|
26
40
|
- name: Install dependencies
|
|
27
41
|
run: npm ci
|
|
28
42
|
|
package/Cargo.lock
CHANGED
|
@@ -2095,7 +2095,7 @@ dependencies = [
|
|
|
2095
2095
|
|
|
2096
2096
|
[[package]]
|
|
2097
2097
|
name = "mint-cli"
|
|
2098
|
-
version = "1.6.
|
|
2098
|
+
version = "1.6.4"
|
|
2099
2099
|
dependencies = [
|
|
2100
2100
|
"anyhow",
|
|
2101
2101
|
"base64 0.22.1",
|
|
@@ -2113,7 +2113,7 @@ dependencies = [
|
|
|
2113
2113
|
|
|
2114
2114
|
[[package]]
|
|
2115
2115
|
name = "mint-core"
|
|
2116
|
-
version = "1.6.
|
|
2116
|
+
version = "1.6.4"
|
|
2117
2117
|
dependencies = [
|
|
2118
2118
|
"base64 0.22.1",
|
|
2119
2119
|
"chrono",
|
|
@@ -2134,7 +2134,7 @@ dependencies = [
|
|
|
2134
2134
|
|
|
2135
2135
|
[[package]]
|
|
2136
2136
|
name = "mint-desktop"
|
|
2137
|
-
version = "1.6.
|
|
2137
|
+
version = "1.6.4"
|
|
2138
2138
|
dependencies = [
|
|
2139
2139
|
"base64 0.22.1",
|
|
2140
2140
|
"dirs",
|
package/Cargo.toml
CHANGED
package/README.md
CHANGED
|
@@ -16,27 +16,27 @@ The desktop application and native CLI share the same Rust domain layer, so chat
|
|
|
16
16
|
memory, knowledge, tools, safety policies, and integrations behave consistently
|
|
17
17
|
across both interfaces.
|
|
18
18
|
|
|
19
|
-
##
|
|
19
|
+
## <img src="assets/features.svg" width="24" height="24" valign="middle" /> What Mint Can Do
|
|
20
20
|
|
|
21
21
|
Mint is a local-first AI assistant running on your machine, capable of handling tasks via either the desktop application or the terminal interface (CLI):
|
|
22
22
|
|
|
23
23
|
---
|
|
24
24
|
|
|
25
|
-
### 1.
|
|
25
|
+
### 1. <img src="assets/chat.svg" width="18" height="18" valign="middle" /> AI Chat & Multi-Providers
|
|
26
26
|
- Connect to **Gemini, OpenAI, Anthropic (Claude), Ollama (Local), Hugging Face**, and LM Studio.
|
|
27
27
|
- Run private local LLMs inside your machine using Ollama or connect to leading cloud APIs.
|
|
28
28
|
- Supports system instructions, temperature adjustments, voice replies, and image analysis (Multimodal).
|
|
29
29
|
|
|
30
30
|
---
|
|
31
31
|
|
|
32
|
-
### 2.
|
|
32
|
+
### 2. <img src="assets/live2d.svg" width="18" height="18" valign="middle" /> Interactive Live2D Desktop Assistant
|
|
33
33
|
- An interactive anime avatar (**Shiroko**) displayed right on your desktop with gaze tracking (eye/face follows your mouse pointer).
|
|
34
34
|
- Toggle expression changes and cycle through character accessories dynamically.
|
|
35
35
|
- Custom interaction zones (Head, Cheek, Hands, Body) that trigger unique animations and message toasts.
|
|
36
36
|
|
|
37
37
|
---
|
|
38
38
|
|
|
39
|
-
### 3.
|
|
39
|
+
### 3. <img src="assets/code.svg" width="18" height="18" valign="middle" /> Autonomous Code Agent
|
|
40
40
|
- Run code agent loops via `/code <task>` or the terminal command `mint code agent "<task>"`.
|
|
41
41
|
- Scan your project workspace, build multi-file implementation plans, fix test suite errors, and write edits automatically.
|
|
42
42
|
- Run local tests, cargo checks, and shell commands.
|
|
@@ -45,20 +45,20 @@ Mint is a local-first AI assistant running on your machine, capable of handling
|
|
|
45
45
|
|
|
46
46
|
---
|
|
47
47
|
|
|
48
|
-
### 4.
|
|
48
|
+
### 4. <img src="assets/memory.svg" width="18" height="18" valign="middle" /> Long-Term Memory & Knowledge Base
|
|
49
49
|
- Persistent conversation memory stored locally in SQLite. Manage user profile memory with `/memory set/get` or CLI commands.
|
|
50
50
|
- Index local directories, text files, and documentation to build your private searchable knowledge base.
|
|
51
51
|
|
|
52
52
|
---
|
|
53
53
|
|
|
54
|
-
### 5.
|
|
54
|
+
### 5. <img src="assets/tools.svg" width="18" height="18" valign="middle" /> Tool & MCP Integrations
|
|
55
55
|
- Support **Model Context Protocol (MCP)** to connect tools like Google/Brave Search, Filesystem servers, and GitHub context.
|
|
56
56
|
- **Auto GitHub Link Resolver:** Automatically detects GitHub URLs in chat messages (CLI, Web, and Desktop) and Code Agent tasks. It fetches and injects the repository's metadata, directory structure, and README as prompt context, serving as an instant fallback when the GitHub MCP server is not active.
|
|
57
57
|
- Local plugins for Spotify playback control, Google Calendar, Gmail drafts, and Notion workspace reading.
|
|
58
58
|
|
|
59
59
|
---
|
|
60
60
|
|
|
61
|
-
### 6.
|
|
61
|
+
### 6. <img src="assets/bridges.svg" width="18" height="18" valign="middle" /> Messaging Bridges
|
|
62
62
|
- Bridge your local AI assistant to messaging services: **Telegram, Discord Gateway, Discord RPC, Slack, LINE, and WhatsApp**.
|
|
63
63
|
- Host local chatbot webhooks that relay chat traffic into your configured LLM.
|
|
64
64
|
> [!TIP]
|
|
@@ -66,16 +66,23 @@ Mint is a local-first AI assistant running on your machine, capable of handling
|
|
|
66
66
|
|
|
67
67
|
---
|
|
68
68
|
|
|
69
|
-
### 7.
|
|
69
|
+
### 7. <img src="assets/screencapture.svg" width="18" height="18" valign="middle" /> Screen Capture & Translation
|
|
70
70
|
- Capture screen snapshots for instant visual analysis by the AI.
|
|
71
71
|
- Real-time continuous overlay translation of specific screen regions.
|
|
72
72
|
|
|
73
73
|
---
|
|
74
74
|
|
|
75
|
+
### 8. <img src="assets/imagegen.svg" width="18" height="18" valign="middle" /> AI Image Generation
|
|
76
|
+
- Generate high-quality images directly from chat or terminal using **DALL-E 3, Stability AI (Stable Diffusion), Ideogram, Replicate (Flux)**, and Google NanoBanana.
|
|
77
|
+
- Supports aspect ratio selections, negative prompts, custom image counts, and automatic storage of generated pictures to the local library.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
75
81
|
## Highlights
|
|
76
82
|
|
|
77
83
|
- Multi-provider chat with Gemini, OpenAI, Anthropic, Ollama, Hugging Face, and
|
|
78
84
|
local OpenAI-compatible endpoints.
|
|
85
|
+
- Image generation using DALL-E 3, Stability AI, Ideogram, Replicate, and NanoBanana.
|
|
79
86
|
- Native streaming responses, SQLite-backed memory, tasks, searchable local
|
|
80
87
|
knowledge, skills, and semantic code search.
|
|
81
88
|
- Desktop dashboard with a Live2D assistant, model interaction areas, pictures,
|
|
@@ -89,22 +96,21 @@ Mint is a local-first AI assistant running on your machine, capable of handling
|
|
|
89
96
|
Cloud API integrations.
|
|
90
97
|
- Signed Tauri update checks with an explicit approval step before installation.
|
|
91
98
|
|
|
92
|
-
##
|
|
93
|
-
|
|
94
|
-
| Desktop assistant | Settings |
|
|
95
|
-
| --- | --- |
|
|
96
|
-
|  |  |
|
|
99
|
+
## <img src="assets/setup.svg" width="24" height="24" valign="middle" /> Prerequisites
|
|
97
100
|
|
|
98
|
-
|
|
101
|
+
Before you can build or run Mint locally, make sure you have the following system tools installed:
|
|
99
102
|
|
|
100
|
-
|
|
103
|
+
| Tool | Description | Required For |
|
|
104
|
+
| :--- | :--- | :--- |
|
|
105
|
+
| **Node.js & npm** | JavaScript runtime and package manager | Frontend UI (React, Vite, TypeScript) |
|
|
106
|
+
| **Rust Toolchain** | Rust compiler (`rustc`) and package manager (`cargo`) | Shared domain logic, CLI, and Tauri backend |
|
|
107
|
+
| **System Dependencies** | Native OS libraries (compiler tools, dbus, webkit) | Compiling window GUI, Webview rendering, and OS utilities |
|
|
101
108
|
|
|
102
|
-
|
|
103
|
-
- A Rust toolchain
|
|
104
|
-
- Tauri v2 native build dependencies for your operating system
|
|
109
|
+
### Linux Dependencies
|
|
105
110
|
|
|
106
|
-
|
|
111
|
+
Install the required C compilers, WebKitGTK, and system libraries for your specific Linux distribution:
|
|
107
112
|
|
|
113
|
+
**Debian / Ubuntu / Linux Mint:**
|
|
108
114
|
```bash
|
|
109
115
|
sudo apt-get install -y \
|
|
110
116
|
build-essential curl file pkg-config wget \
|
|
@@ -113,8 +119,25 @@ sudo apt-get install -y \
|
|
|
113
119
|
poppler-utils unzip patchelf
|
|
114
120
|
```
|
|
115
121
|
|
|
116
|
-
|
|
117
|
-
|
|
122
|
+
**Fedora / RHEL / CentOS:**
|
|
123
|
+
```bash
|
|
124
|
+
sudo dnf groupinstall -y "Development Tools"
|
|
125
|
+
sudo dnf install -y \
|
|
126
|
+
webkit2gtk4.1-devel openssl-devel curl wget glibc-devel \
|
|
127
|
+
dbus-devel libayatana-appindicator-devel librsvg2-devel \
|
|
128
|
+
poppler-utils unzip patchelf
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Arch Linux:**
|
|
132
|
+
```bash
|
|
133
|
+
sudo pacman -Syu --needed \
|
|
134
|
+
base-devel webkit2gtk-4.1 openssl curl wget \
|
|
135
|
+
dbus libayatana-appindicator librsvg \
|
|
136
|
+
poppler unzip patchelf
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
> [!TIP]
|
|
140
|
+
> **Other Platforms:** If you are developing on macOS or Windows, follow the official [Tauri Prerequisites Guide](https://v2.tauri.app/start/prerequisites/) to set up your build environment.
|
|
118
141
|
|
|
119
142
|
## Installation
|
|
120
143
|
|
|
@@ -139,6 +162,7 @@ mint setup
|
|
|
139
162
|
mint
|
|
140
163
|
mint web
|
|
141
164
|
mint chat "Hello"
|
|
165
|
+
mint imagine "A futuristic mint-colored robot" --aspect 16:9
|
|
142
166
|
```
|
|
143
167
|
|
|
144
168
|
Most integrations can be configured from:
|
|
@@ -184,6 +208,42 @@ To install the `mint` command-line tool globally:
|
|
|
184
208
|
* **Option C (Development Shell Alias):**
|
|
185
209
|
If you are actively modifying code and want changes to reflect instantly, set up the alias under the [Setting up the mint Shortcut](#setting-up-the-mint-shortcut) section.
|
|
186
210
|
|
|
211
|
+
|
|
212
|
+
## User Interface
|
|
213
|
+
|
|
214
|
+
### Desktop App
|
|
215
|
+
<table width="100%">
|
|
216
|
+
<tr>
|
|
217
|
+
<td align="center" width="50%"><b>Desktop Assistant</b></td>
|
|
218
|
+
<td align="center" width="50%"><b>Settings</b></td>
|
|
219
|
+
</tr>
|
|
220
|
+
<tr>
|
|
221
|
+
<td><img src="assets/Mint_Desktop.png" alt="Desktop Assistant" /></td>
|
|
222
|
+
<td><img src="assets/Setting.png" alt="Settings" /></td>
|
|
223
|
+
</tr>
|
|
224
|
+
</table>
|
|
225
|
+
|
|
226
|
+
### Web UI
|
|
227
|
+
<table width="100%">
|
|
228
|
+
<tr>
|
|
229
|
+
<td align="center"><img src="assets/Mint_Web.png" alt="Web UI" /></td>
|
|
230
|
+
</tr>
|
|
231
|
+
</table>
|
|
232
|
+
|
|
233
|
+
### CLI
|
|
234
|
+
<table width="100%">
|
|
235
|
+
<tr>
|
|
236
|
+
<td align="center"><img src="assets/Mint_CLI.png" alt="CLI" /></td>
|
|
237
|
+
</tr>
|
|
238
|
+
</table>
|
|
239
|
+
|
|
240
|
+
### Workspace & Agent
|
|
241
|
+
<table width="100%">
|
|
242
|
+
<tr>
|
|
243
|
+
<td align="center"><img src="assets/Mint_WorkSpace.png" alt="Workspace & Agent" /></td>
|
|
244
|
+
</tr>
|
|
245
|
+
</table>
|
|
246
|
+
|
|
187
247
|
## Desktop Assistant
|
|
188
248
|
|
|
189
249
|
The desktop application provides:
|
|
@@ -290,6 +350,7 @@ mint chat "<message>"
|
|
|
290
350
|
| `mint config doctor` | Validate the local setup |
|
|
291
351
|
| `mint providers` | List configured AI providers |
|
|
292
352
|
| `mint chat "<message>"` | Send one chat message |
|
|
353
|
+
| `mint imagine "<prompt>"` | Generate an image from a text prompt |
|
|
293
354
|
| `mint memory recent` | Show recent conversation memory |
|
|
294
355
|
| `mint task list` | List all tasks (pending and completed) |
|
|
295
356
|
| `mint task pending` | List pending tasks |
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#10b981" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
|
|
2
|
+
<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/>
|
|
3
|
+
<path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/>
|
|
4
|
+
</svg>
|
package/assets/chat.svg
ADDED
package/assets/code.svg
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#10b981" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
|
|
2
|
+
<path d="M11 20A7 7 0 0 1 9.8 6.1C15.5 5 17 4.48 19 2c1 2 2 3.5 1 9.8a7 7 0 0 1-9 8.2zm0 0v-5m-2.5 1.5l3-3m-4.5 0l4-4" />
|
|
3
|
+
</svg>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#10b981" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
|
|
2
|
+
<rect x="3" y="3" width="18" height="18" rx="2" ry="2"/>
|
|
3
|
+
<circle cx="8.5" cy="8.5" r="1.5"/>
|
|
4
|
+
<polyline points="21 15 16 10 5 21"/>
|
|
5
|
+
</svg>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#10b981" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
|
|
2
|
+
<circle cx="12" cy="12" r="10"/>
|
|
3
|
+
<path d="M8 14s1.5 2 4 2 4-2 4-2"/>
|
|
4
|
+
<line x1="9" y1="9" x2="9.01" y2="9"/>
|
|
5
|
+
<line x1="15" y1="9" x2="15.01" y2="9"/>
|
|
6
|
+
</svg>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#10b981" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
|
|
2
|
+
<ellipse cx="12" cy="5" rx="9" ry="3"/>
|
|
3
|
+
<path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5"/>
|
|
4
|
+
<path d="M3 12c0 1.66 4 3 9 3s9-1.34 9-3"/>
|
|
5
|
+
</svg>
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#10b981" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
|
|
2
|
+
<path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/>
|
|
3
|
+
<circle cx="12" cy="13" r="4"/>
|
|
4
|
+
</svg>
|
package/assets/setup.svg
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#10b981" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
|
|
2
|
+
<path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"/>
|
|
3
|
+
</svg>
|
package/assets/tools.svg
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#10b981" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
|
|
2
|
+
<circle cx="12" cy="12" r="3"/>
|
|
3
|
+
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/>
|
|
4
|
+
</svg>
|
package/bin/mint
CHANGED
|
Binary file
|
|
@@ -178,7 +178,7 @@ pub async fn run_code_agent_with_options(
|
|
|
178
178
|
));
|
|
179
179
|
render_live_status(&mut status);
|
|
180
180
|
}
|
|
181
|
-
tokio::time::sleep(Duration::
|
|
181
|
+
tokio::time::sleep(Duration::from_millis(150)).await;
|
|
182
182
|
}
|
|
183
183
|
});
|
|
184
184
|
}
|
|
@@ -479,6 +479,7 @@ struct LiveStatus {
|
|
|
479
479
|
committed_activities: usize,
|
|
480
480
|
committed_tasks: usize,
|
|
481
481
|
rendered_lines: usize,
|
|
482
|
+
spinner_tick: usize,
|
|
482
483
|
}
|
|
483
484
|
|
|
484
485
|
#[derive(Debug, Clone)]
|
|
@@ -551,7 +552,10 @@ fn render_live_status(status: &mut LiveStatus) {
|
|
|
551
552
|
lines.extend(activities_lines(&status.activities[activities_start..]));
|
|
552
553
|
lines.extend(explored_lines(&status.explored[explored_start..]));
|
|
553
554
|
if let Some(thinking) = &status.thinking {
|
|
554
|
-
|
|
555
|
+
let frames = &["⣾", "⣽", "⣻", "⢿", "⡿", "⣟", "⣯", "⣷"];
|
|
556
|
+
let frame = frames[status.spinner_tick % frames.len()];
|
|
557
|
+
status.spinner_tick += 1;
|
|
558
|
+
lines.push(format!("{MINT}{frame}{RESET}{BRIGHT}{thinking}{RESET}"));
|
|
555
559
|
}
|
|
556
560
|
if lines.is_empty() {
|
|
557
561
|
return;
|
|
@@ -7,10 +7,10 @@ use std::{
|
|
|
7
7
|
};
|
|
8
8
|
|
|
9
9
|
use mint_core::{
|
|
10
|
-
CHAT_CLI_ID, Capability, ChatRequest, CodeEdit, CodePatchHunk,
|
|
11
|
-
MintConfig, TaskStore, apply_code_edits, assert_path_capability, build_code_patch,
|
|
10
|
+
CHAT_CLI_ID, Capability, ChatRequest, CodeEdit, CodePatchHunk, ImageGenRequest, KnowledgeStore,
|
|
11
|
+
MemoryStore, MintConfig, TaskStore, apply_code_edits, assert_path_capability, build_code_patch,
|
|
12
12
|
build_symbol_index, classify_shell_command, config_path, create_folder, execute_native_plugin,
|
|
13
|
-
fetch_github_repo_summary, find_paths, index_semantic_code, initialize_config,
|
|
13
|
+
fetch_github_repo_summary, find_paths, generate_images, index_semantic_code, initialize_config,
|
|
14
14
|
inspect_code_plan, list_code_files, load_config, native_plugins,
|
|
15
15
|
orchestrate_chat_stream_with_fallback, orchestrate_chat_with_fallback, parse_github_url,
|
|
16
16
|
propose_code_edits, read_code_file, repository_summary, run_shell_command, search_code,
|
|
@@ -180,6 +180,23 @@ enum Command {
|
|
|
180
180
|
Onboard,
|
|
181
181
|
/// Interactively manage enabled agent tools.
|
|
182
182
|
Setup,
|
|
183
|
+
/// Generate an image from a text prompt using NanoBanana (Gemini image model).
|
|
184
|
+
Imagine {
|
|
185
|
+
/// Text description of the image to generate.
|
|
186
|
+
prompt: String,
|
|
187
|
+
/// Aspect ratio: 1:1, 16:9, 9:16, or 4:3 [default: 1:1]
|
|
188
|
+
#[arg(long, default_value = "1:1")]
|
|
189
|
+
aspect: String,
|
|
190
|
+
/// Number of images to generate (1–4) [default: 1]
|
|
191
|
+
#[arg(long, default_value_t = 1)]
|
|
192
|
+
count: u8,
|
|
193
|
+
/// Negative prompt — elements to avoid in the image
|
|
194
|
+
#[arg(long)]
|
|
195
|
+
negative: Option<String>,
|
|
196
|
+
/// Save the first generated image to this path
|
|
197
|
+
#[arg(long)]
|
|
198
|
+
output: Option<PathBuf>,
|
|
199
|
+
},
|
|
183
200
|
}
|
|
184
201
|
|
|
185
202
|
#[derive(Debug, Subcommand)]
|
|
@@ -926,6 +943,72 @@ async fn main() -> Result<()> {
|
|
|
926
943
|
launch_mint_target(target).await?;
|
|
927
944
|
}
|
|
928
945
|
}
|
|
946
|
+
Command::Imagine {
|
|
947
|
+
prompt,
|
|
948
|
+
aspect,
|
|
949
|
+
count,
|
|
950
|
+
negative,
|
|
951
|
+
output,
|
|
952
|
+
} => {
|
|
953
|
+
let config = load_config()?;
|
|
954
|
+
let count = count.clamp(1, 4);
|
|
955
|
+
eprint!("{DIM}✦ Generating {count} image(s)...{RESET}");
|
|
956
|
+
let _ = std::io::stderr().flush();
|
|
957
|
+
let request = ImageGenRequest {
|
|
958
|
+
prompt: prompt.clone(),
|
|
959
|
+
negative_prompt: negative,
|
|
960
|
+
aspect_ratio: Some(aspect),
|
|
961
|
+
num_images: Some(count),
|
|
962
|
+
model: None,
|
|
963
|
+
provider: None,
|
|
964
|
+
};
|
|
965
|
+
match generate_images(&config, &request).await {
|
|
966
|
+
Ok(result) => {
|
|
967
|
+
eprintln!(
|
|
968
|
+
"\r{MINT}✦ Generated {} image(s) {RESET}",
|
|
969
|
+
result.images.len()
|
|
970
|
+
);
|
|
971
|
+
let data_uris: Vec<String> = result
|
|
972
|
+
.images
|
|
973
|
+
.iter()
|
|
974
|
+
.map(|img| img.data_uri.clone())
|
|
975
|
+
.collect();
|
|
976
|
+
match mint_core::save_chat_images(
|
|
977
|
+
data_uris,
|
|
978
|
+
Some(result.provider.clone()),
|
|
979
|
+
Some(prompt.clone()),
|
|
980
|
+
) {
|
|
981
|
+
Ok(saved) => {
|
|
982
|
+
for entry in &saved {
|
|
983
|
+
println!("{MINT}✓{RESET} Saved: {}", entry.path.display());
|
|
984
|
+
}
|
|
985
|
+
// If --output specified, copy first image there
|
|
986
|
+
if let (Some(out_path), Some(first)) = (&output, saved.first()) {
|
|
987
|
+
match std::fs::copy(&first.path, out_path) {
|
|
988
|
+
Ok(_) => println!(
|
|
989
|
+
"{MINT}✓{RESET} Copied to: {}",
|
|
990
|
+
out_path.display()
|
|
991
|
+
),
|
|
992
|
+
Err(e) => eprintln!(
|
|
993
|
+
"{WARN}Warning: could not copy to output path: {e}{RESET}"
|
|
994
|
+
),
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
if let Some(desc) = &result.description {
|
|
998
|
+
if !desc.is_empty() {
|
|
999
|
+
println!("\n{DIM}{desc}{RESET}");
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
Err(e) => eprintln!("{ERROR}Failed to save images: {e}{RESET}"),
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
Err(e) => {
|
|
1007
|
+
eprintln!("{ERROR}✗ Image generation failed: {e}{RESET}");
|
|
1008
|
+
anyhow::bail!("image generation failed: {e}");
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
929
1012
|
},
|
|
930
1013
|
}
|
|
931
1014
|
Ok(())
|
|
@@ -1214,6 +1297,10 @@ async fn handle_slash_command(
|
|
|
1214
1297
|
("/memory clear", "Clear all interactions"),
|
|
1215
1298
|
("/memory get <key>", "Read a profile value"),
|
|
1216
1299
|
("/memory set <key> <val>", "Store a profile value"),
|
|
1300
|
+
(
|
|
1301
|
+
"/image-provider [name]",
|
|
1302
|
+
"List image gen providers or switch default provider",
|
|
1303
|
+
),
|
|
1217
1304
|
("/mcp list", "List configured MCP servers"),
|
|
1218
1305
|
("/mcp allow <server> <tool>", "Allow an MCP tool"),
|
|
1219
1306
|
("/stats", "Show session statistics"),
|
|
@@ -1270,6 +1357,55 @@ async fn handle_slash_command(
|
|
|
1270
1357
|
Some(SlashResult::Handled)
|
|
1271
1358
|
}
|
|
1272
1359
|
|
|
1360
|
+
"/image-provider" => {
|
|
1361
|
+
let mut available = Vec::new();
|
|
1362
|
+
if !session.config.api_key.trim().is_empty() {
|
|
1363
|
+
available.push("nanobanana");
|
|
1364
|
+
}
|
|
1365
|
+
if !session.config.openai_api_key.trim().is_empty() {
|
|
1366
|
+
available.push("dalle");
|
|
1367
|
+
}
|
|
1368
|
+
if !session.config.stability_api_key.trim().is_empty() {
|
|
1369
|
+
available.push("stability");
|
|
1370
|
+
}
|
|
1371
|
+
if !session.config.ideogram_api_key.trim().is_empty() {
|
|
1372
|
+
available.push("ideogram");
|
|
1373
|
+
}
|
|
1374
|
+
if !session.config.replicate_api_key.trim().is_empty() {
|
|
1375
|
+
available.push("replicate");
|
|
1376
|
+
}
|
|
1377
|
+
if available.is_empty() {
|
|
1378
|
+
available.push("nanobanana");
|
|
1379
|
+
}
|
|
1380
|
+
|
|
1381
|
+
if rest.is_empty() {
|
|
1382
|
+
println!("\n{BLUE}Configured image generation providers:{RESET}");
|
|
1383
|
+
for p in &available {
|
|
1384
|
+
let active = if p == &session.config.image_gen_provider.as_str() {
|
|
1385
|
+
format!(" {MINT}← active{RESET}")
|
|
1386
|
+
} else {
|
|
1387
|
+
String::new()
|
|
1388
|
+
};
|
|
1389
|
+
println!(" {p}{active}");
|
|
1390
|
+
}
|
|
1391
|
+
println!();
|
|
1392
|
+
} else {
|
|
1393
|
+
if available.contains(&rest) {
|
|
1394
|
+
session.config.image_gen_provider = rest.to_owned();
|
|
1395
|
+
match mint_core::save_config(&session.config) {
|
|
1396
|
+
Ok(()) => println!(
|
|
1397
|
+
"{DIM}Switched default image provider to: {}{RESET}\n",
|
|
1398
|
+
session.config.image_gen_provider
|
|
1399
|
+
),
|
|
1400
|
+
Err(error) => println!("{ERROR}Config error:{RESET} {error}"),
|
|
1401
|
+
}
|
|
1402
|
+
} else {
|
|
1403
|
+
println!("{ERROR}Provider '{rest}' is not configured or invalid.{RESET}\n");
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
Some(SlashResult::Handled)
|
|
1407
|
+
}
|
|
1408
|
+
|
|
1273
1409
|
"/clear" | "/reset" => {
|
|
1274
1410
|
println!("Clear conversation history? [y/N] ");
|
|
1275
1411
|
if let Ok(true) = confirm("Clear conversation history? [y/N] ") {
|
|
@@ -1884,6 +2020,10 @@ const AUTOCOMPLETE_COMMANDS: &[(&str, &str)] = &[
|
|
|
1884
2020
|
("/help", "Show help menu"),
|
|
1885
2021
|
("/fast", "Toggle fast mode (hide thinking traces)"),
|
|
1886
2022
|
("/models", "List AI providers or switch active provider"),
|
|
2023
|
+
(
|
|
2024
|
+
"/image-provider",
|
|
2025
|
+
"List image gen providers or switch default provider",
|
|
2026
|
+
),
|
|
1887
2027
|
("/clear", "Clear conversation history"),
|
|
1888
2028
|
("/cd", "Change active workspace directory"),
|
|
1889
2029
|
("/image", "Attach image from disk"),
|
|
@@ -1963,9 +2103,9 @@ fn draw_input_box(
|
|
|
1963
2103
|
let highlight_idx = tab_index.map(|idx| idx % matches.len());
|
|
1964
2104
|
for (i, (cmd, desc)) in matches.iter().enumerate() {
|
|
1965
2105
|
if Some(i) == highlight_idx {
|
|
1966
|
-
println!(" {BLUE}▶ {:<
|
|
2106
|
+
println!(" {BLUE}▶ {:<16}{RESET} {DIM}- {}{RESET}", cmd, desc);
|
|
1967
2107
|
} else {
|
|
1968
|
-
println!(" {DIM}{:<
|
|
2108
|
+
println!(" {DIM}{:<16} - {}{RESET}", cmd, desc);
|
|
1969
2109
|
}
|
|
1970
2110
|
}
|
|
1971
2111
|
}
|