@pheem49/mint 1.8.2 → 1.10.0
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/Cargo.lock +55 -3
- package/Cargo.toml +2 -1
- package/Release_Note.md +297 -107
- package/bin/mint +0 -0
- package/crates/mint-cli/Cargo.toml +1 -0
- package/crates/mint-cli/src/actions.rs +233 -0
- package/crates/mint-cli/src/agent.rs +382 -127
- package/crates/mint-cli/src/gmail.rs +22 -2
- package/crates/mint-cli/src/image.rs +8 -8
- package/crates/mint-cli/src/interactive.rs +2888 -0
- package/crates/mint-cli/src/main.rs +391 -2506
- package/crates/mint-cli/src/markdown.rs +294 -0
- package/crates/mint-cli/src/onboard.rs +152 -109
- package/crates/mint-cli/src/setup.rs +143 -143
- package/crates/mint-cli/src/updater.rs +48 -6
- package/crates/mint-core/Cargo.toml +1 -0
- package/crates/mint-core/src/agent_loop.rs +1 -0
- package/crates/mint-core/src/api_server.rs +431 -65
- package/crates/mint-core/src/browser.rs +630 -102
- package/crates/mint-core/src/channels.rs +105 -6
- package/crates/mint-core/src/chat.rs +174 -11
- package/crates/mint-core/src/code_tools.rs +47 -31
- package/crates/mint-core/src/config.rs +302 -17
- package/crates/mint-core/src/image_gen.rs +299 -38
- package/crates/mint-core/src/lib.rs +10 -7
- package/crates/mint-core/src/mcp.rs +119 -6
- package/crates/mint-core/src/memory.rs +6 -1
- package/crates/mint-core/src/orchestration.rs +237 -96
- package/crates/mint-core/src/pictures.rs +67 -5
- package/crates/mint-core/src/semantic.rs +1 -1
- package/crates/mint-core/src/shell.rs +1 -1
- package/crates/mint-core/src/skills.rs +128 -25
- package/crates/mint-core/src/video_gen.rs +235 -0
- package/package.json +8 -2
- package/shared-modules/linux-audio/fluidsynth2-static.json +9 -3
- package/shared-modules/linux-audio/fluidsynth2.json +8 -2
- package/shared-modules/linux-audio/lilv.json +26 -19
- package/shared-modules/linux-audio/lv2.json +0 -1
- package/shared-modules/luajit/luajit.json +2 -2
- package/skills-lock.json +41 -0
- package/src/renderer/index-web.html +1 -1
- package/src/renderer/index.html +1 -1
- package/src/renderer/shared/components/AgentActivityTable.tsx +25 -6
- package/src/renderer/shared/constants/slashCommands.ts +27 -0
- package/src/renderer/shared/platform.ts +3 -0
- package/src/renderer/shared/types.ts +4 -0
- package/src/renderer/shared/utils/approval.tsx +86 -7
- package/src/renderer/shared/utils/fileIcons.ts +135 -0
- package/src/renderer/shared/utils/markdown.tsx +217 -88
- package/src/renderer/shared/utils/slashCommandProcessor.ts +239 -0
- package/src/renderer/src/components/ChatPanel.tsx +486 -69
- package/src/renderer/src/components/DashboardSidebar.tsx +11 -2
- package/src/renderer/src/components/ImageStudioPanel.tsx +87 -4
- package/src/renderer/src/components/MintDashboard.tsx +195 -7
- package/src/renderer/src/components/PicturesLibrary.tsx +156 -15
- package/src/renderer/src/components/Settings/AgentsTab.tsx +21 -2
- package/src/renderer/src/components/Settings/AutomationTab.tsx +316 -18
- package/src/renderer/src/components/Settings/GeneralTab.tsx +795 -413
- package/src/renderer/src/components/Settings/PluginsTab.tsx +304 -70
- package/src/renderer/src/components/Settings/ThemeTab.tsx +6 -1
- package/src/renderer/src/components/SettingsWindow.tsx +106 -3
- package/src/renderer/src/components/VeoStudioPanel.tsx +549 -0
- package/src/renderer/src/components/WorkspacePanel.tsx +7 -125
- package/src/renderer/src/css/image-studio.css +106 -0
- package/src/renderer/src/css/settings.css +158 -0
- package/src/renderer/src/css/styles.css +368 -1
- package/src/renderer/src/css/veo-studio.css +626 -0
- package/src/renderer/src/index.css +1 -0
- package/src/renderer/src/tauri.ts +144 -17
- package/src/renderer/src-web/components/ChatPanel.tsx +385 -93
- package/src/renderer/src-web/components/DashboardSidebar.tsx +16 -1
- package/src/renderer/src-web/components/ImageStudioPanel.tsx +87 -4
- package/src/renderer/src-web/components/MintDashboard.tsx +156 -5
- package/src/renderer/src-web/components/PicturesLibrary.tsx +155 -15
- package/src/renderer/src-web/components/Settings/AgentsTab.tsx +21 -2
- package/src/renderer/src-web/components/Settings/AutomationTab.tsx +316 -18
- package/src/renderer/src-web/components/Settings/GeneralTab.tsx +795 -411
- package/src/renderer/src-web/components/Settings/PluginsTab.tsx +304 -70
- package/src/renderer/src-web/components/Settings/ThemeTab.tsx +6 -1
- package/src/renderer/src-web/components/SettingsWindow.tsx +110 -3
- package/src/renderer/src-web/components/VeoStudioPanel.tsx +549 -0
- package/src/renderer/src-web/css/image-studio.css +106 -0
- package/src/renderer/src-web/css/settings.css +158 -0
- package/src/renderer/src-web/css/styles.css +369 -1
- package/src/renderer/src-web/css/veo-studio.css +650 -0
- package/src/renderer/src-web/index.css +1 -0
- package/src/renderer/src-web/tauri.ts +135 -16
- package/src-tauri/src/desktop.rs +18 -16
- package/src-tauri/src/discord_rpc.rs +1 -1
- package/src-tauri/src/lib.rs +155 -25
- package/src-tauri/src/webhooks.rs +45 -31
- package/src-tauri/src/workflows.rs +1 -0
- package/src-tauri/tauri.conf.json +1 -1
- package/temp_gridgeist/AGENTS.md +8 -0
- package/temp_gridgeist/CHANGELOG.md +130 -0
- package/temp_gridgeist/LICENSE +21 -0
- package/temp_gridgeist/README.md +323 -0
- package/temp_gridgeist/README.th.md +325 -0
- package/temp_gridgeist/skills/gridgeist/SKILL.md +88 -0
- package/temp_gridgeist/skills/gridgeist/agents/openai.yaml +9 -0
- package/temp_gridgeist/skills/gridgeist/assets/gridgeist-small.svg +10 -0
- package/temp_gridgeist/skills/gridgeist/assets/gridgeist.png +0 -0
- package/temp_gridgeist/skills/gridgeist/assets/gridgeist.svg +18 -0
- package/temp_gridgeist/skills/gridgeist/references/design-language.md +88 -0
- package/temp_gridgeist/skills/gridgeist/references/review-checklist.md +128 -0
- package/temp_gridgeist/skills/gridgeist/references/system-contract.md +109 -0
|
@@ -2,7 +2,10 @@ use std::{
|
|
|
2
2
|
collections::BTreeMap,
|
|
3
3
|
io::{BufRead, BufReader, Write},
|
|
4
4
|
process::{Child, Command, Stdio},
|
|
5
|
-
sync::
|
|
5
|
+
sync::{
|
|
6
|
+
atomic::{AtomicBool, Ordering},
|
|
7
|
+
mpsc,
|
|
8
|
+
},
|
|
6
9
|
time::{Duration, Instant},
|
|
7
10
|
};
|
|
8
11
|
|
|
@@ -12,7 +15,8 @@ use thiserror::Error;
|
|
|
12
15
|
|
|
13
16
|
use crate::{ConfigError, MintConfig, load_config, save_config};
|
|
14
17
|
|
|
15
|
-
const MCP_TIMEOUT: Duration = Duration::from_secs(
|
|
18
|
+
const MCP_TIMEOUT: Duration = Duration::from_secs(30);
|
|
19
|
+
static OAUTH_DETECTED: AtomicBool = AtomicBool::new(false);
|
|
16
20
|
|
|
17
21
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
|
18
22
|
pub struct McpServer {
|
|
@@ -21,6 +25,8 @@ pub struct McpServer {
|
|
|
21
25
|
pub args: Vec<String>,
|
|
22
26
|
#[serde(default)]
|
|
23
27
|
pub env: BTreeMap<String, String>,
|
|
28
|
+
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
29
|
+
pub icon: Option<String>,
|
|
24
30
|
}
|
|
25
31
|
|
|
26
32
|
#[derive(Debug, Error)]
|
|
@@ -33,7 +39,9 @@ pub enum McpError {
|
|
|
33
39
|
InvalidEnvironment,
|
|
34
40
|
#[error("MCP server '{0}' is not configured")]
|
|
35
41
|
MissingServer(String),
|
|
36
|
-
#[error(
|
|
42
|
+
#[error(
|
|
43
|
+
"MCP tool '{server}/{tool}' is not allowed by policy. To allow it, please run: /mcp allow {server} {tool} (or /mcp allow {server} * to allow all tools on this server)"
|
|
44
|
+
)]
|
|
37
45
|
NotAllowed { server: String, tool: String },
|
|
38
46
|
#[error("unable to start MCP server '{command}': {source}")]
|
|
39
47
|
Start {
|
|
@@ -82,6 +90,7 @@ pub fn add_mcp_server(
|
|
|
82
90
|
command: command.into(),
|
|
83
91
|
args,
|
|
84
92
|
env: parse_env(env)?,
|
|
93
|
+
icon: None,
|
|
85
94
|
},
|
|
86
95
|
);
|
|
87
96
|
save_mcp_servers(&mut config, servers)
|
|
@@ -186,18 +195,86 @@ fn parse_env(values: Vec<String>) -> Result<BTreeMap<String, String>, McpError>
|
|
|
186
195
|
.collect()
|
|
187
196
|
}
|
|
188
197
|
|
|
198
|
+
fn find_url(line: &str) -> Option<String> {
|
|
199
|
+
let start_idx = line.find("http://").or_else(|| line.find("https://"))?;
|
|
200
|
+
let rest = &line[start_idx..];
|
|
201
|
+
let end_idx = rest
|
|
202
|
+
.find(|c: char| c.is_whitespace() || c == '"' || c == '\'' || c == '<' || c == '>')
|
|
203
|
+
.unwrap_or(rest.len());
|
|
204
|
+
let url = rest[..end_idx].to_string();
|
|
205
|
+
|
|
206
|
+
let lower = url.to_lowercase();
|
|
207
|
+
if lower.contains("registry.npmjs.org")
|
|
208
|
+
|| lower.contains("npmjs.com")
|
|
209
|
+
|| lower.contains("github.com/modelcontextprotocol")
|
|
210
|
+
{
|
|
211
|
+
return None;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if lower.contains("oauth")
|
|
215
|
+
|| lower.contains("auth")
|
|
216
|
+
|| lower.contains("login")
|
|
217
|
+
|| lower.contains("google.com")
|
|
218
|
+
|| lower.contains("authorize")
|
|
219
|
+
{
|
|
220
|
+
Some(url)
|
|
221
|
+
} else {
|
|
222
|
+
None
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
fn open_url_in_browser(url: &str) -> std::io::Result<()> {
|
|
227
|
+
#[cfg(target_os = "linux")]
|
|
228
|
+
{
|
|
229
|
+
Command::new("xdg-open").arg(url).spawn().map(|_| ())
|
|
230
|
+
}
|
|
231
|
+
#[cfg(target_os = "macos")]
|
|
232
|
+
{
|
|
233
|
+
Command::new("open").arg(url).spawn().map(|_| ())
|
|
234
|
+
}
|
|
235
|
+
#[cfg(target_os = "windows")]
|
|
236
|
+
{
|
|
237
|
+
Command::new("cmd")
|
|
238
|
+
.args(&["/C", "start", url])
|
|
239
|
+
.spawn()
|
|
240
|
+
.map(|_| ())
|
|
241
|
+
}
|
|
242
|
+
#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))]
|
|
243
|
+
{
|
|
244
|
+
let _ = url;
|
|
245
|
+
Ok(())
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
189
249
|
fn start_server(server: &McpServer) -> Result<Child, McpError> {
|
|
190
250
|
let mut process = Command::new(&server.command)
|
|
191
251
|
.args(&server.args)
|
|
192
252
|
.envs(&server.env)
|
|
193
253
|
.stdin(Stdio::piped())
|
|
194
254
|
.stdout(Stdio::piped())
|
|
195
|
-
.stderr(Stdio::
|
|
255
|
+
.stderr(Stdio::piped())
|
|
196
256
|
.spawn()
|
|
197
257
|
.map_err(|source| McpError::Start {
|
|
198
258
|
command: server.command.clone(),
|
|
199
259
|
source,
|
|
200
260
|
})?;
|
|
261
|
+
|
|
262
|
+
if let Some(stderr) = process.stderr.take() {
|
|
263
|
+
std::thread::spawn(move || {
|
|
264
|
+
let reader = BufReader::new(stderr);
|
|
265
|
+
for line in reader.lines().map_while(Result::ok) {
|
|
266
|
+
if let Some(url) = find_url(&line) {
|
|
267
|
+
println!(
|
|
268
|
+
"\n\x1b[1;33m[MCP Authorization Needed]\x1b[0m Opening browser to authenticate: {}\n",
|
|
269
|
+
url
|
|
270
|
+
);
|
|
271
|
+
OAUTH_DETECTED.store(true, Ordering::Relaxed);
|
|
272
|
+
let _ = open_url_in_browser(&url);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
|
|
201
278
|
write_message(
|
|
202
279
|
&mut process,
|
|
203
280
|
&json!({
|
|
@@ -224,26 +301,62 @@ fn exchange(process: &mut Child, request: Value) -> Result<Value, McpError> {
|
|
|
224
301
|
let (sender, receiver) = mpsc::channel();
|
|
225
302
|
std::thread::spawn(move || {
|
|
226
303
|
for line in BufReader::new(stdout).lines().map_while(Result::ok) {
|
|
304
|
+
if let Some(url) = find_url(&line) {
|
|
305
|
+
println!(
|
|
306
|
+
"\n\x1b[1;33m[MCP Authorization Needed]\x1b[0m Opening browser to authenticate: {}\n",
|
|
307
|
+
url
|
|
308
|
+
);
|
|
309
|
+
OAUTH_DETECTED.store(true, Ordering::Relaxed);
|
|
310
|
+
let _ = open_url_in_browser(&url);
|
|
311
|
+
}
|
|
227
312
|
if let Ok(value) = serde_json::from_str::<Value>(&line) {
|
|
228
313
|
let _ = sender.send(value);
|
|
229
314
|
}
|
|
230
315
|
}
|
|
231
316
|
});
|
|
317
|
+
|
|
318
|
+
let timeout = if OAUTH_DETECTED.load(Ordering::Relaxed) {
|
|
319
|
+
Duration::from_secs(120)
|
|
320
|
+
} else {
|
|
321
|
+
MCP_TIMEOUT
|
|
322
|
+
};
|
|
323
|
+
|
|
232
324
|
let started = Instant::now();
|
|
233
|
-
while started.elapsed() <
|
|
325
|
+
while started.elapsed() < timeout {
|
|
234
326
|
let response = receiver
|
|
235
|
-
.recv_timeout(
|
|
327
|
+
.recv_timeout(timeout.saturating_sub(started.elapsed()))
|
|
236
328
|
.map_err(|_| McpError::Timeout)?;
|
|
237
329
|
if response["id"] == 2 {
|
|
330
|
+
OAUTH_DETECTED.store(false, Ordering::Relaxed);
|
|
238
331
|
if let Some(error) = response.get("error") {
|
|
239
332
|
return Err(McpError::Tool(error.clone()));
|
|
240
333
|
}
|
|
241
334
|
return Ok(response.get("result").cloned().unwrap_or(Value::Null));
|
|
242
335
|
}
|
|
243
336
|
}
|
|
337
|
+
OAUTH_DETECTED.store(false, Ordering::Relaxed);
|
|
244
338
|
Err(McpError::Timeout)
|
|
245
339
|
}
|
|
246
340
|
|
|
341
|
+
pub fn list_server_tools(config: &MintConfig, server_name: &str) -> Result<Value, McpError> {
|
|
342
|
+
let servers = configured_mcp_servers(config)?;
|
|
343
|
+
let server = servers
|
|
344
|
+
.get(server_name)
|
|
345
|
+
.ok_or_else(|| McpError::MissingServer(server_name.into()))?;
|
|
346
|
+
let mut process = start_server(server)?;
|
|
347
|
+
let result = exchange(
|
|
348
|
+
&mut process,
|
|
349
|
+
json!({
|
|
350
|
+
"jsonrpc": "2.0",
|
|
351
|
+
"id": 2,
|
|
352
|
+
"method": "tools/list",
|
|
353
|
+
"params": {}
|
|
354
|
+
}),
|
|
355
|
+
);
|
|
356
|
+
let _ = process.kill();
|
|
357
|
+
result
|
|
358
|
+
}
|
|
359
|
+
|
|
247
360
|
fn write_message(process: &mut Child, message: &Value) -> Result<(), McpError> {
|
|
248
361
|
let stdin = process.stdin.as_mut().ok_or(McpError::MissingStdin)?;
|
|
249
362
|
writeln!(stdin, "{message}").map_err(McpError::Write)?;
|
|
@@ -58,6 +58,8 @@ pub struct LearnedSkill {
|
|
|
58
58
|
pub source_path: String,
|
|
59
59
|
pub content: String,
|
|
60
60
|
pub created_at: String,
|
|
61
|
+
#[serde(default)]
|
|
62
|
+
pub description: Option<String>,
|
|
61
63
|
}
|
|
62
64
|
|
|
63
65
|
#[derive(Debug, Clone, Serialize, PartialEq, Eq)]
|
|
@@ -624,12 +626,15 @@ fn ensure_column(
|
|
|
624
626
|
}
|
|
625
627
|
|
|
626
628
|
fn learned_skill_row(row: &rusqlite::Row<'_>) -> Result<LearnedSkill, rusqlite::Error> {
|
|
629
|
+
let content: String = row.get(3)?;
|
|
630
|
+
let description = crate::skills::parse_skill_description(&content);
|
|
627
631
|
Ok(LearnedSkill {
|
|
628
632
|
id: row.get(0)?,
|
|
629
633
|
name: row.get(1)?,
|
|
630
634
|
source_path: row.get(2)?,
|
|
631
|
-
content
|
|
635
|
+
content,
|
|
632
636
|
created_at: row.get(4)?,
|
|
637
|
+
description,
|
|
633
638
|
})
|
|
634
639
|
}
|
|
635
640
|
|