@pheem49/mint 1.7.0 → 1.7.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/Cargo.toml +1 -1
- package/crates/mint-cli/src/agent.rs +1 -1
- package/crates/mint-cli/src/main.rs +47 -24
- package/crates/mint-cli/src/setup.rs +1 -1
- package/crates/mint-core/src/api_server.rs +2 -6
- package/crates/mint-core/src/plugins.rs +4 -1
- package/package.json +12 -2
- package/src-tauri/src/lib.rs +1 -2
- package/src-tauri/tauri.conf.json +1 -1
package/Cargo.toml
CHANGED
|
@@ -804,7 +804,7 @@ fn format_markdown_bold(text: &str) -> String {
|
|
|
804
804
|
let mut leading_spaces = 0;
|
|
805
805
|
let mut is_list_item = false;
|
|
806
806
|
let mut marker_char = '-';
|
|
807
|
-
|
|
807
|
+
|
|
808
808
|
for (idx, c) in line.char_indices() {
|
|
809
809
|
if c.is_whitespace() {
|
|
810
810
|
leading_spaces += c.len_utf8();
|
|
@@ -1109,7 +1109,9 @@ fn process_inline_bold(s: &str) -> String {
|
|
|
1109
1109
|
fn format_line(line: &str) -> String {
|
|
1110
1110
|
let mut formatted = line.to_string();
|
|
1111
1111
|
let trimmed = line.trim_start();
|
|
1112
|
-
if (trimmed.starts_with("- ") || trimmed.starts_with("* ") || trimmed.starts_with("+ "))
|
|
1112
|
+
if (trimmed.starts_with("- ") || trimmed.starts_with("* ") || trimmed.starts_with("+ "))
|
|
1113
|
+
&& trimmed.len() >= 2
|
|
1114
|
+
{
|
|
1113
1115
|
let leading_len = line.len() - trimmed.len();
|
|
1114
1116
|
let leading_spaces = &line[..leading_len];
|
|
1115
1117
|
formatted = format!("{}•{}", leading_spaces, &trimmed[1..]);
|
|
@@ -1169,7 +1171,11 @@ fn render_markdown_table(table_lines: &[String]) -> String {
|
|
|
1169
1171
|
let mut has_separator = false;
|
|
1170
1172
|
let mut separator_idx = None;
|
|
1171
1173
|
for (i, row) in rows.iter().enumerate() {
|
|
1172
|
-
if row.iter().all(|col|
|
|
1174
|
+
if row.iter().all(|col| {
|
|
1175
|
+
col.chars()
|
|
1176
|
+
.all(|c| c == '-' || c == ':' || c == ' ' || c == '\t')
|
|
1177
|
+
}) && !row.is_empty()
|
|
1178
|
+
{
|
|
1173
1179
|
has_separator = true;
|
|
1174
1180
|
separator_idx = Some(i);
|
|
1175
1181
|
break;
|
|
@@ -1202,7 +1208,7 @@ fn render_markdown_table(table_lines: &[String]) -> String {
|
|
|
1202
1208
|
|
|
1203
1209
|
let num_cols = rows.iter().map(|r| r.len()).max().unwrap_or(0);
|
|
1204
1210
|
let mut col_widths = vec![0; num_cols];
|
|
1205
|
-
|
|
1211
|
+
|
|
1206
1212
|
if let Some(ref header) = header_row {
|
|
1207
1213
|
for (i, col) in header.iter().enumerate() {
|
|
1208
1214
|
if i < num_cols {
|
|
@@ -1220,18 +1226,19 @@ fn render_markdown_table(table_lines: &[String]) -> String {
|
|
|
1220
1226
|
|
|
1221
1227
|
let mut rendered = String::new();
|
|
1222
1228
|
|
|
1223
|
-
let draw_border =
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
+
let draw_border =
|
|
1230
|
+
|left: &str, mid: &str, right: &str, fill: &str, widths: &[usize]| -> String {
|
|
1231
|
+
let mut s = left.to_string();
|
|
1232
|
+
for (i, &w) in widths.iter().enumerate() {
|
|
1233
|
+
s.push_str(&fill.repeat(w + 2));
|
|
1234
|
+
if i < widths.len() - 1 {
|
|
1235
|
+
s.push_str(mid);
|
|
1236
|
+
}
|
|
1229
1237
|
}
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
};
|
|
1238
|
+
s.push_str(right);
|
|
1239
|
+
s.push('\n');
|
|
1240
|
+
s
|
|
1241
|
+
};
|
|
1235
1242
|
|
|
1236
1243
|
rendered.push_str(&draw_border("┌", "┬", "┐", "─", &col_widths));
|
|
1237
1244
|
|
|
@@ -1240,7 +1247,11 @@ fn render_markdown_table(table_lines: &[String]) -> String {
|
|
|
1240
1247
|
for (i, col) in header.iter().enumerate() {
|
|
1241
1248
|
let width = unicode_width(col);
|
|
1242
1249
|
let padding = col_widths[i] - width;
|
|
1243
|
-
rendered.push_str(&format!(
|
|
1250
|
+
rendered.push_str(&format!(
|
|
1251
|
+
" \x1b[1;36m{}\x1b[0m{}",
|
|
1252
|
+
col,
|
|
1253
|
+
" ".repeat(padding + 1)
|
|
1254
|
+
));
|
|
1244
1255
|
rendered.push_str("│");
|
|
1245
1256
|
}
|
|
1246
1257
|
rendered.push('\n');
|
|
@@ -1571,7 +1582,10 @@ async fn handle_slash_command(
|
|
|
1571
1582
|
("/paste [prompt]", "Attach image from clipboard"),
|
|
1572
1583
|
("Ctrl+V", "Paste clipboard image as [Image #1]"),
|
|
1573
1584
|
("/learn <path>", "Import a persistent .md or .txt skill"),
|
|
1574
|
-
(
|
|
1585
|
+
(
|
|
1586
|
+
"/plugins <name> [prompt]",
|
|
1587
|
+
"Generate a skill.md file for a plugin/skill",
|
|
1588
|
+
),
|
|
1575
1589
|
("/memory list", "Show recent interactions"),
|
|
1576
1590
|
("/memory clear", "Clear all interactions"),
|
|
1577
1591
|
("/memory get <key>", "Read a profile value"),
|
|
@@ -1965,23 +1979,25 @@ async fn handle_slash_command(
|
|
|
1965
1979
|
println!("\n{BLUE}────────────────────────────────────────────{RESET}");
|
|
1966
1980
|
println!("{MINT} Available Plugins & Skills{RESET}");
|
|
1967
1981
|
println!("{BLUE}────────────────────────────────────────────{RESET}");
|
|
1968
|
-
|
|
1982
|
+
|
|
1969
1983
|
println!("{MINT}Native Plugins:{RESET}");
|
|
1970
1984
|
for p in native_plugins() {
|
|
1971
1985
|
println!(" - {BLUE}{:<20}{RESET} {}", p.name, p.description);
|
|
1972
1986
|
}
|
|
1973
|
-
|
|
1987
|
+
|
|
1974
1988
|
println!("\n{MINT}Custom Skills/Plugins (Active):{RESET}");
|
|
1975
1989
|
let mut active_skills = std::collections::HashSet::new();
|
|
1976
1990
|
if let Ok(memory) = MemoryStore::open_default() {
|
|
1977
1991
|
match memory.learned_skills(100) {
|
|
1978
1992
|
Ok(skills) => {
|
|
1979
1993
|
if skills.is_empty() {
|
|
1980
|
-
println!(
|
|
1994
|
+
println!(
|
|
1995
|
+
" {DIM}(No custom skills/plugins learned yet. Use '/learn <path>' to add one.){RESET}"
|
|
1996
|
+
);
|
|
1981
1997
|
} else {
|
|
1982
1998
|
for s in &skills {
|
|
1983
1999
|
println!(" - {BLUE}{:<20}{RESET} {}", s.name, s.source_path);
|
|
1984
|
-
|
|
2000
|
+
|
|
1985
2001
|
// Try to store canonicalized active path
|
|
1986
2002
|
if let Ok(canon) = Path::new(&s.source_path).canonicalize() {
|
|
1987
2003
|
active_skills.insert(canon);
|
|
@@ -2005,7 +2021,9 @@ async fn handle_slash_command(
|
|
|
2005
2021
|
if path.is_file() {
|
|
2006
2022
|
if let Some(ext) = path.extension().and_then(|e| e.to_str()) {
|
|
2007
2023
|
if matches!(ext.to_ascii_lowercase().as_str(), "md" | "txt") {
|
|
2008
|
-
if let Some(name) =
|
|
2024
|
+
if let Some(name) =
|
|
2025
|
+
path.file_name().and_then(|n| n.to_str())
|
|
2026
|
+
{
|
|
2009
2027
|
if let Ok(canon_path) = path.canonicalize() {
|
|
2010
2028
|
local_files.push((name.to_owned(), canon_path));
|
|
2011
2029
|
} else {
|
|
@@ -2016,7 +2034,7 @@ async fn handle_slash_command(
|
|
|
2016
2034
|
}
|
|
2017
2035
|
}
|
|
2018
2036
|
}
|
|
2019
|
-
|
|
2037
|
+
|
|
2020
2038
|
let inactive_files: Vec<_> = local_files
|
|
2021
2039
|
.into_iter()
|
|
2022
2040
|
.filter(|(_, full_path)| !active_skills.contains(full_path))
|
|
@@ -2024,9 +2042,14 @@ async fn handle_slash_command(
|
|
|
2024
2042
|
.collect();
|
|
2025
2043
|
|
|
2026
2044
|
if !inactive_files.is_empty() {
|
|
2027
|
-
println!(
|
|
2045
|
+
println!(
|
|
2046
|
+
"\n{MINT}Local Skill Files (Found but not learned/active yet):{RESET}"
|
|
2047
|
+
);
|
|
2028
2048
|
for file in inactive_files {
|
|
2029
|
-
println!(
|
|
2049
|
+
println!(
|
|
2050
|
+
" - {WARN}{:<20}{RESET} skills/{} {DIM}(Type '/learn skills/{}' to activate){RESET}",
|
|
2051
|
+
file, file, file
|
|
2052
|
+
);
|
|
2030
2053
|
}
|
|
2031
2054
|
}
|
|
2032
2055
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
use anyhow::Result;
|
|
2
2
|
use crossterm::event::{self, Event, KeyCode};
|
|
3
3
|
use crossterm::terminal::{disable_raw_mode, enable_raw_mode};
|
|
4
|
-
use mint_core::{load_config,
|
|
4
|
+
use mint_core::{load_config, native_plugins, save_config};
|
|
5
5
|
use std::io::{self, Write};
|
|
6
6
|
|
|
7
7
|
struct ToolOption {
|
|
@@ -291,12 +291,8 @@ pub async fn start_api_server(port: u16) -> Result<(), std::io::Error> {
|
|
|
291
291
|
)
|
|
292
292
|
.is_ok()
|
|
293
293
|
{
|
|
294
|
-
send_json_response(
|
|
295
|
-
|
|
296
|
-
"200 OK",
|
|
297
|
-
"{\"status\":\"ok\"}",
|
|
298
|
-
)
|
|
299
|
-
.await;
|
|
294
|
+
send_json_response(socket, "200 OK", "{\"status\":\"ok\"}")
|
|
295
|
+
.await;
|
|
300
296
|
return;
|
|
301
297
|
}
|
|
302
298
|
}
|
|
@@ -242,7 +242,10 @@ fn github(instruction: &str) -> Result<String, PluginError> {
|
|
|
242
242
|
if id.chars().all(|c| c.is_ascii_digit()) {
|
|
243
243
|
run("gh", &["issue", "view", id])
|
|
244
244
|
} else {
|
|
245
|
-
invalid(
|
|
245
|
+
invalid(
|
|
246
|
+
"github",
|
|
247
|
+
"view_issue/issue view requires a numeric issue ID",
|
|
248
|
+
)
|
|
246
249
|
}
|
|
247
250
|
}
|
|
248
251
|
["list_prs"] | ["pr", "list"] => run("gh", &["pr", "list", "--limit", "10"]),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pheem49/mint",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.1",
|
|
4
4
|
"description": "A native Tauri desktop AI assistant with a Rust backend and React UI.",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev:web": "vite --config vite.config.web.ts",
|
|
@@ -27,7 +27,17 @@
|
|
|
27
27
|
"cli": "cargo run -p mint-cli --",
|
|
28
28
|
"postinstall": "cargo build -p mint-cli --release && mkdir -p bin && cp target/release/mint bin/mint"
|
|
29
29
|
},
|
|
30
|
-
"keywords": [
|
|
30
|
+
"keywords": [
|
|
31
|
+
"mint",
|
|
32
|
+
"tauri",
|
|
33
|
+
"ai",
|
|
34
|
+
"assistant",
|
|
35
|
+
"desktop",
|
|
36
|
+
"cli",
|
|
37
|
+
"rust",
|
|
38
|
+
"react",
|
|
39
|
+
"agent"
|
|
40
|
+
],
|
|
31
41
|
"repository": {
|
|
32
42
|
"type": "git",
|
|
33
43
|
"url": "git+https://github.com/Pheem49/Mint.git"
|
package/src-tauri/src/lib.rs
CHANGED
|
@@ -552,8 +552,7 @@ fn save_interaction_agent_activity(
|
|
|
552
552
|
interaction_id: i64,
|
|
553
553
|
activity: Vec<AgentProgress>,
|
|
554
554
|
) -> Result<(), String> {
|
|
555
|
-
let activity_json =
|
|
556
|
-
serde_json::to_string(&activity).map_err(|error| error.to_string())?;
|
|
555
|
+
let activity_json = serde_json::to_string(&activity).map_err(|error| error.to_string())?;
|
|
557
556
|
MemoryStore::open_default()
|
|
558
557
|
.and_then(|memory| {
|
|
559
558
|
memory
|