@pheem49/mint 1.5.0 → 1.5.2
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 +35 -1
- package/main.js +28 -14
- package/mint-cli-logic.js +3 -119
- package/mint-cli.js +201 -500
- package/models/Shiroko_Model/Shiroko/Shiroko_Core/72d86db84cfa9730b894c241fd24c0db.png +0 -0
- package/models/Shiroko_Model/Shiroko/Shiroko_Core/items_pinned_to_model.json +14 -0
- package/models/Shiroko_Model/Shiroko/Shiroko_Core//345/221/206/347/214/253.exp3.json +40 -0
- package/models/Shiroko_Model/Shiroko/Shiroko_Core//345/221/206/347/214/253/347/234/274/347/217/240/346/221/207/346/231/203.exp3.json +15 -0
- package/models/Shiroko_Model/Shiroko/Shiroko_Core//345/233/264/350/243/231.exp3.json +10 -0
- package/models/Shiroko_Model/Shiroko/Shiroko_Core//346/213/215/347/205/247.exp3.json +50 -0
- package/models/Shiroko_Model/Shiroko/Shiroko_Core//346/213/277/347/254/224.exp3.json +10 -0
- package/models/Shiroko_Model/Shiroko/Shiroko_Core//347/202/271/344/270/200/344/270/213.exp3.json +15 -0
- package/models/Shiroko_Model/Shiroko/Shiroko_Core//347/214/253/345/222/252/346/273/244/351/225/234.exp3.json +10 -0
- package/models/Shiroko_Model/Shiroko/Shiroko_Core//347/234/274/351/225/234.exp3.json +10 -0
- package/models/Shiroko_Model/Shiroko/Shiroko_Core//351/235/242/351/245/2740.4096/texture_00.png +0 -0
- package/models/Shiroko_Model/Shiroko/Shiroko_Core//351/235/242/351/245/2740.4096/texture_01.png +0 -0
- package/models/Shiroko_Model/Shiroko/Shiroko_Core//351/235/242/351/245/2740.4096/texture_02.png +0 -0
- package/models/Shiroko_Model/Shiroko/Shiroko_Core//351/235/242/351/245/2740.4096/texture_03.png +0 -0
- package/models/Shiroko_Model/Shiroko/Shiroko_Core//351/235/242/351/245/2740.cdi3.json +1498 -0
- package/models/Shiroko_Model/Shiroko/Shiroko_Core//351/235/242/351/245/2740.moc3 +0 -0
- package/models/Shiroko_Model/Shiroko/Shiroko_Core//351/235/242/351/245/2740.model3.json +47 -0
- package/models/Shiroko_Model/Shiroko/Shiroko_Core//351/235/242/351/245/2740.physics3.json +6658 -0
- package/models/Shiroko_Model/Shiroko/Shiroko_Core//351/235/242/351/245/2740.vtube.json +1299 -0
- package/models/Shiroko_Model/Shiroko//342/232/241/351/253/230/344/272/256/342/232/241/344/275/277/347/224/250/346/225/231/347/250/213/344/270/216/346/263/250/346/204/217/344/272/213/351/241/271.txt +23 -0
- package/package.json +40 -17
- package/src/AI_Brain/Gemini_API.js +147 -46
- package/src/AI_Brain/autonomous_brain.js +2 -1
- package/src/AI_Brain/memory_store.js +299 -3
- package/src/AI_Brain/proactive_engine.js +12 -2
- package/src/Automation_Layer/browser_automation.js +26 -24
- package/src/CLI/approval_handler.js +42 -0
- package/src/CLI/chat_router.js +18 -6
- package/src/CLI/chat_ui.js +583 -52
- package/src/CLI/cli_colors.js +32 -0
- package/src/CLI/cli_formatters.js +89 -0
- package/src/CLI/code_agent.js +369 -71
- package/src/CLI/image_input.js +90 -0
- package/src/CLI/intent_detectors.js +181 -0
- package/src/CLI/interactive_chat.js +479 -0
- package/src/CLI/list_features.js +3 -0
- package/src/CLI/onboarding.js +72 -15
- package/src/CLI/repo_summarizer.js +282 -0
- package/src/CLI/semantic_code_search.js +312 -0
- package/src/CLI/skill_manager.js +41 -0
- package/src/CLI/slash_command_handler.js +418 -0
- package/src/CLI/symbol_indexer.js +231 -0
- package/src/CLI/updater.js +6 -4
- package/src/Channels/discord_bridge.js +11 -13
- package/src/Channels/line_bridge.js +10 -10
- package/src/Channels/slack_bridge.js +7 -12
- package/src/Channels/telegram_bridge.js +6 -14
- package/src/Channels/whatsapp_bridge.js +11 -9
- package/src/System/action_executor.js +59 -10
- package/src/System/chat_history_manager.js +20 -12
- package/src/System/config_manager.js +31 -1
- package/src/System/granular_automation.js +122 -53
- package/src/System/optional_require.js +23 -0
- package/src/System/proactive_loop.js +19 -3
- package/src/System/safety_manager.js +108 -0
- package/src/System/sandbox_runner.js +182 -0
- package/src/System/system_automation.js +127 -81
- package/src/System/system_info.js +70 -0
- package/src/System/tool_registry.js +280 -0
- package/src/System/window_manager.js +4 -2
- package/src/UI/live2d_manager.js +566 -0
- package/src/UI/renderer.js +339 -21
- package/src/UI/settings.css +655 -420
- package/src/UI/settings.html +478 -432
- package/src/UI/settings.js +10 -8
- package/src/UI/styles.css +516 -31
- package/.codex +0 -0
- package/docs/assets/Agent_Mint.png +0 -0
- package/docs/assets/CLI_Screen.png +0 -0
- package/docs/assets/Settings.png +0 -0
- package/docs/assets/icon.png +0 -0
- package/docs/guide.html +0 -632
- package/docs/index.html +0 -133
- package/docs/style.css +0 -579
- package/index.html +0 -16
- package/src/UI/index.html +0 -126
- package/tech_news.txt +0 -3
- package/test_knowledge.txt +0 -3
- package/tests/action_executor_safety.test.js +0 -67
- package/tests/agent_orchestrator.test.js +0 -41
- package/tests/chat_router.test.js +0 -42
- package/tests/code_agent.test.js +0 -69
- package/tests/config_manager.test.js +0 -141
- package/tests/docker.test.js +0 -46
- package/tests/file_operations.test.js +0 -57
- package/tests/gmail.test.js +0 -135
- package/tests/gmail_auth.test.js +0 -129
- package/tests/google_calendar.test.js +0 -113
- package/tests/google_tts_urls.test.js +0 -24
- package/tests/memory_store.test.js +0 -185
- package/tests/notion.test.js +0 -121
- package/tests/provider_routing.test.js +0 -83
- package/tests/safety_manager.test.js +0 -40
- package/tests/spotify.test.js +0 -201
- package/tests/system_monitor.test.js +0 -37
- package/tests/updater.test.js +0 -32
- package/tests/workspace_manager.test.js +0 -56
|
@@ -1,9 +1,15 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { requireOptional } = require('../System/optional_require');
|
|
2
4
|
const { handleChat } = require('../AI_Brain/Gemini_API');
|
|
3
5
|
|
|
4
6
|
class DiscordBridge {
|
|
5
7
|
constructor(token) {
|
|
6
8
|
this.token = token;
|
|
9
|
+
const { Client, GatewayIntentBits, Partials } = requireOptional(
|
|
10
|
+
'discord.js',
|
|
11
|
+
'npm install discord.js'
|
|
12
|
+
);
|
|
7
13
|
this.client = new Client({
|
|
8
14
|
intents: [
|
|
9
15
|
GatewayIntentBits.Guilds,
|
|
@@ -21,30 +27,22 @@ class DiscordBridge {
|
|
|
21
27
|
});
|
|
22
28
|
|
|
23
29
|
this.client.on('messageCreate', async (message) => {
|
|
24
|
-
// Ignore bot messages
|
|
25
30
|
if (message.author.bot) return;
|
|
26
|
-
|
|
27
|
-
// Handle DMs or Mentions
|
|
28
31
|
const isDM = !message.guild;
|
|
29
32
|
const isMentioned = message.mentions.has(this.client.user);
|
|
30
33
|
|
|
31
34
|
if (isDM || isMentioned) {
|
|
32
35
|
try {
|
|
33
|
-
// Clean up the message if it's a mention
|
|
34
36
|
let cleanContent = message.content;
|
|
35
37
|
if (isMentioned) {
|
|
36
|
-
cleanContent = message.content
|
|
38
|
+
cleanContent = message.content
|
|
39
|
+
.replace(`<@!${this.client.user.id}>`, '')
|
|
40
|
+
.replace(`<@${this.client.user.id}>`, '')
|
|
41
|
+
.trim();
|
|
37
42
|
}
|
|
38
|
-
|
|
39
43
|
if (!cleanContent) return;
|
|
40
|
-
|
|
41
|
-
// Show typing indicator
|
|
42
44
|
await message.channel.sendTyping();
|
|
43
|
-
|
|
44
|
-
// Send to Mint AI Brain
|
|
45
45
|
const result = await handleChat(cleanContent);
|
|
46
|
-
|
|
47
|
-
// Reply to user
|
|
48
46
|
if (result && result.response) {
|
|
49
47
|
await message.reply(result.response);
|
|
50
48
|
}
|
|
@@ -1,22 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { requireOptional } = require('../System/optional_require');
|
|
3
4
|
const { handleChat } = require('../AI_Brain/Gemini_API');
|
|
4
5
|
|
|
5
6
|
class LineBridge {
|
|
6
7
|
constructor(credentials) {
|
|
8
|
+
this._line = requireOptional('@line/bot-sdk', 'npm install @line/bot-sdk express');
|
|
9
|
+
this._express = requireOptional('express', 'npm install @line/bot-sdk express');
|
|
7
10
|
this.config = {
|
|
8
11
|
channelAccessToken: credentials.accessToken,
|
|
9
12
|
channelSecret: credentials.secret,
|
|
10
13
|
};
|
|
11
|
-
this.port
|
|
12
|
-
this.client = new
|
|
14
|
+
this.port = credentials.port || 3000;
|
|
15
|
+
this.client = new this._line.messagingApi.MessagingApiClient({
|
|
13
16
|
channelAccessToken: credentials.accessToken
|
|
14
17
|
});
|
|
15
|
-
this.app
|
|
18
|
+
this.app = this._express();
|
|
16
19
|
}
|
|
17
20
|
|
|
18
21
|
async connect() {
|
|
19
|
-
this.app.post('/callback',
|
|
22
|
+
this.app.post('/callback', this._line.middleware(this.config), (req, res) => {
|
|
20
23
|
Promise
|
|
21
24
|
.all(req.body.events.map(event => this.handleEvent(event)))
|
|
22
25
|
.then((result) => res.json(result))
|
|
@@ -36,7 +39,6 @@ class LineBridge {
|
|
|
36
39
|
if (event.type !== 'message' || event.message.type !== 'text') {
|
|
37
40
|
return Promise.resolve(null);
|
|
38
41
|
}
|
|
39
|
-
|
|
40
42
|
try {
|
|
41
43
|
const result = await handleChat(event.message.text);
|
|
42
44
|
if (result && result.response) {
|
|
@@ -51,9 +53,7 @@ class LineBridge {
|
|
|
51
53
|
}
|
|
52
54
|
|
|
53
55
|
async disconnect() {
|
|
54
|
-
if (this.server)
|
|
55
|
-
this.server.close();
|
|
56
|
-
}
|
|
56
|
+
if (this.server) this.server.close();
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { requireOptional } = require('../System/optional_require');
|
|
2
4
|
const { handleChat } = require('../AI_Brain/Gemini_API');
|
|
3
5
|
|
|
4
6
|
class SlackBridge {
|
|
5
7
|
constructor(credentials) {
|
|
8
|
+
const { App } = requireOptional('@slack/bolt', 'npm install @slack/bolt');
|
|
6
9
|
this.app = new App({
|
|
7
10
|
token: credentials.botToken,
|
|
8
11
|
appToken: credentials.appToken,
|
|
@@ -15,24 +18,18 @@ class SlackBridge {
|
|
|
15
18
|
try {
|
|
16
19
|
const text = event.text.replace(/<@.*?>/g, '').trim();
|
|
17
20
|
if (!text) return;
|
|
18
|
-
|
|
19
21
|
const result = await handleChat(text);
|
|
20
|
-
if (result && result.response)
|
|
21
|
-
await say(result.response);
|
|
22
|
-
}
|
|
22
|
+
if (result && result.response) await say(result.response);
|
|
23
23
|
} catch (err) {
|
|
24
24
|
console.error('[Slack Bridge] Error processing app_mention:', err);
|
|
25
25
|
}
|
|
26
26
|
});
|
|
27
27
|
|
|
28
28
|
this.app.event('message', async ({ event, say }) => {
|
|
29
|
-
// Only respond in DMs
|
|
30
29
|
if (event.channel_type === 'im') {
|
|
31
30
|
try {
|
|
32
31
|
const result = await handleChat(event.text);
|
|
33
|
-
if (result && result.response)
|
|
34
|
-
await say(result.response);
|
|
35
|
-
}
|
|
32
|
+
if (result && result.response) await say(result.response);
|
|
36
33
|
} catch (err) {
|
|
37
34
|
console.error('[Slack Bridge] Error processing message:', err);
|
|
38
35
|
}
|
|
@@ -44,9 +41,7 @@ class SlackBridge {
|
|
|
44
41
|
}
|
|
45
42
|
|
|
46
43
|
async disconnect() {
|
|
47
|
-
if (this.app)
|
|
48
|
-
await this.app.stop();
|
|
49
|
-
}
|
|
44
|
+
if (this.app) await this.app.stop();
|
|
50
45
|
}
|
|
51
46
|
}
|
|
52
47
|
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { requireOptional } = require('../System/optional_require');
|
|
2
4
|
const { handleChat } = require('../AI_Brain/Gemini_API');
|
|
3
5
|
|
|
4
6
|
class TelegramBridge {
|
|
5
7
|
constructor(token) {
|
|
6
8
|
this.token = token;
|
|
9
|
+
const { Telegraf } = requireOptional('telegraf', 'npm install telegraf');
|
|
7
10
|
this.bot = new Telegraf(token);
|
|
8
11
|
}
|
|
9
12
|
|
|
@@ -12,19 +15,11 @@ class TelegramBridge {
|
|
|
12
15
|
|
|
13
16
|
this.bot.on('text', async (ctx) => {
|
|
14
17
|
try {
|
|
15
|
-
// Show typing status
|
|
16
18
|
await ctx.sendChatAction('typing');
|
|
17
|
-
|
|
18
19
|
const message = ctx.message.text;
|
|
19
20
|
if (!message) return;
|
|
20
|
-
|
|
21
|
-
// Send to Mint AI Brain
|
|
22
21
|
const result = await handleChat(message);
|
|
23
|
-
|
|
24
|
-
// Reply to user
|
|
25
|
-
if (result && result.response) {
|
|
26
|
-
await ctx.reply(result.response);
|
|
27
|
-
}
|
|
22
|
+
if (result && result.response) await ctx.reply(result.response);
|
|
28
23
|
} catch (err) {
|
|
29
24
|
console.error('[Telegram Bridge] Error processing message:', err);
|
|
30
25
|
await ctx.reply('ขออภัยค่ะ เกิดข้อผิดพลาดบางอย่างในการประมวลผลข้อความ');
|
|
@@ -34,15 +29,12 @@ class TelegramBridge {
|
|
|
34
29
|
this.bot.launch();
|
|
35
30
|
console.log('[Telegram Bridge] Bot started!');
|
|
36
31
|
|
|
37
|
-
// Enable graceful stop
|
|
38
32
|
process.once('SIGINT', () => this.bot.stop('SIGINT'));
|
|
39
33
|
process.once('SIGTERM', () => this.bot.stop('SIGTERM'));
|
|
40
34
|
}
|
|
41
35
|
|
|
42
36
|
async disconnect() {
|
|
43
|
-
if (this.bot)
|
|
44
|
-
await this.bot.stop();
|
|
45
|
-
}
|
|
37
|
+
if (this.bot) await this.bot.stop();
|
|
46
38
|
}
|
|
47
39
|
}
|
|
48
40
|
|
|
@@ -1,9 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { requireOptional } = require('../System/optional_require');
|
|
3
4
|
const { handleChat } = require('../AI_Brain/Gemini_API');
|
|
4
5
|
|
|
5
6
|
class WhatsappBridge {
|
|
6
7
|
constructor() {
|
|
8
|
+
// Dynamic require — only loads if user has installed whatsapp-web.js
|
|
9
|
+
const { Client, LocalAuth } = requireOptional(
|
|
10
|
+
'whatsapp-web.js',
|
|
11
|
+
'npm install whatsapp-web.js qrcode-terminal'
|
|
12
|
+
);
|
|
13
|
+
this._qrcode = requireOptional('qrcode-terminal', 'npm install qrcode-terminal');
|
|
7
14
|
this.client = new Client({
|
|
8
15
|
authStrategy: new LocalAuth({
|
|
9
16
|
dataPath: require('path').join(require('os').homedir(), '.config', 'mint', 'whatsapp-session')
|
|
@@ -17,7 +24,7 @@ class WhatsappBridge {
|
|
|
17
24
|
async connect() {
|
|
18
25
|
this.client.on('qr', (qr) => {
|
|
19
26
|
console.log('[WhatsApp Bridge] Scan this QR code to login:');
|
|
20
|
-
|
|
27
|
+
this._qrcode.generate(qr, { small: true });
|
|
21
28
|
});
|
|
22
29
|
|
|
23
30
|
this.client.on('ready', () => {
|
|
@@ -26,13 +33,8 @@ class WhatsappBridge {
|
|
|
26
33
|
|
|
27
34
|
this.client.on('message', async (msg) => {
|
|
28
35
|
try {
|
|
29
|
-
// Ignore messages from groups unless mentioned (simple implementation)
|
|
30
36
|
const chat = await msg.getChat();
|
|
31
|
-
if (chat.isGroup)
|
|
32
|
-
// For groups, we could add a mention check here if desired
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
|
|
37
|
+
if (chat.isGroup) return;
|
|
36
38
|
const result = await handleChat(msg.body);
|
|
37
39
|
if (result && result.response) {
|
|
38
40
|
await msg.reply(result.response);
|
|
@@ -1,19 +1,33 @@
|
|
|
1
|
-
|
|
1
|
+
let electronClipboard = null;
|
|
2
|
+
try {
|
|
3
|
+
({ clipboard: electronClipboard } = require('electron'));
|
|
4
|
+
} catch (_) {
|
|
5
|
+
electronClipboard = {
|
|
6
|
+
writeText: () => {}
|
|
7
|
+
};
|
|
8
|
+
}
|
|
2
9
|
const { openApp } = require('../Automation_Layer/open_app');
|
|
3
10
|
const { openWebsite, openSearch } = require('../Automation_Layer/open_website');
|
|
4
11
|
const { performWebAutomation } = require('../Automation_Layer/browser_automation');
|
|
5
12
|
const { createFolder, openFile, deleteFile, findPath } = require('../Automation_Layer/file_operations');
|
|
6
13
|
const { indexFile, indexFolder } = require('../AI_Brain/knowledge_base');
|
|
14
|
+
const { getSystemInfo, getWeather } = require('./system_info');
|
|
7
15
|
const pluginManager = require('../Plugins/plugin_manager');
|
|
8
16
|
const mcpManager = require('../Plugins/mcp_manager');
|
|
9
|
-
const granularAutomation = require('./granular_automation');
|
|
10
17
|
const SystemAutomation = require('./system_automation');
|
|
11
18
|
const safetyManager = require('./safety_manager');
|
|
19
|
+
const toolRegistry = require('./tool_registry');
|
|
20
|
+
const os = require('os');
|
|
21
|
+
const path = require('path');
|
|
12
22
|
|
|
13
23
|
async function executeAction(action, options = {}) {
|
|
14
|
-
|
|
24
|
+
if (process.env.MINT_DEBUG === '1') {
|
|
25
|
+
console.log("Executing action:", action);
|
|
26
|
+
}
|
|
27
|
+
toolRegistry.validateToolInput(action.type, action);
|
|
15
28
|
const clipboard = options.clipboard || electronClipboard;
|
|
16
29
|
const safety = safetyManager.assertActionAllowed(action, {
|
|
30
|
+
allowApproval: options.allowApproval === true,
|
|
17
31
|
allowDangerous: options.allowDangerous === true
|
|
18
32
|
});
|
|
19
33
|
safetyManager.appendActionLog({
|
|
@@ -21,7 +35,7 @@ async function executeAction(action, options = {}) {
|
|
|
21
35
|
action: action.type,
|
|
22
36
|
target: action.target || action.path || '',
|
|
23
37
|
tier: safety.tier,
|
|
24
|
-
approved: options.allowDangerous === true || safety.tier
|
|
38
|
+
approved: options.allowApproval === true || options.allowDangerous === true || safety.tier === safetyManager.TIERS.SAFE
|
|
25
39
|
});
|
|
26
40
|
|
|
27
41
|
switch (action.type) {
|
|
@@ -37,17 +51,23 @@ async function executeAction(action, options = {}) {
|
|
|
37
51
|
case 'web_automation':
|
|
38
52
|
return await performWebAutomation(action.target);
|
|
39
53
|
case 'create_folder':
|
|
54
|
+
safetyManager.assertPathCapability(action.target, 'write', {
|
|
55
|
+
defaultBase: path.join(os.homedir(), 'Desktop')
|
|
56
|
+
});
|
|
40
57
|
createFolder(action.target);
|
|
41
58
|
break;
|
|
42
59
|
case 'open_file': {
|
|
60
|
+
safetyManager.assertPathCapability(action.target, 'read');
|
|
43
61
|
const fileRes = await openFile(action.target);
|
|
44
62
|
return fileRes || `Successfully opened file: ${action.target} ✅`;
|
|
45
63
|
}
|
|
46
64
|
case 'open_folder': {
|
|
65
|
+
safetyManager.assertPathCapability(action.target, 'read');
|
|
47
66
|
const folderRes = await openFile(action.target);
|
|
48
67
|
return folderRes || `Successfully opened folder: ${action.target} ✅`;
|
|
49
68
|
}
|
|
50
69
|
case 'delete_file':
|
|
70
|
+
safetyManager.assertPathCapability(action.target, 'write');
|
|
51
71
|
await deleteFile(action.target);
|
|
52
72
|
break;
|
|
53
73
|
case 'find_path':
|
|
@@ -56,21 +76,33 @@ async function executeAction(action, options = {}) {
|
|
|
56
76
|
clipboard.writeText(action.target);
|
|
57
77
|
break;
|
|
58
78
|
case 'learn_file':
|
|
79
|
+
safetyManager.assertPathCapability(action.target, 'read');
|
|
59
80
|
return await indexFile(action.target);
|
|
60
81
|
case 'learn_folder':
|
|
82
|
+
safetyManager.assertPathCapability(action.target, 'read');
|
|
61
83
|
return await indexFolder(action.target);
|
|
84
|
+
case 'system_info':
|
|
85
|
+
return await handleSystemInfo(action.target);
|
|
62
86
|
case 'mcp_tool': {
|
|
63
87
|
const mcpResult = await mcpManager.callTool(action.server, action.target, action.args);
|
|
64
88
|
return JSON.stringify(mcpResult.content);
|
|
65
89
|
}
|
|
66
|
-
case 'mouse_move':
|
|
90
|
+
case 'mouse_move': {
|
|
91
|
+
const granularAutomation = require('./granular_automation');
|
|
67
92
|
return await granularAutomation.mouseMove(action.x, action.y);
|
|
68
|
-
|
|
93
|
+
}
|
|
94
|
+
case 'mouse_click': {
|
|
95
|
+
const granularAutomation = require('./granular_automation');
|
|
69
96
|
return await granularAutomation.mouseClick(action.x, action.y, action.button || 1);
|
|
70
|
-
|
|
97
|
+
}
|
|
98
|
+
case 'type_text': {
|
|
99
|
+
const granularAutomation = require('./granular_automation');
|
|
71
100
|
return await granularAutomation.typeText(action.target);
|
|
72
|
-
|
|
101
|
+
}
|
|
102
|
+
case 'key_tap': {
|
|
103
|
+
const granularAutomation = require('./granular_automation');
|
|
73
104
|
return await granularAutomation.keyTap(action.target);
|
|
105
|
+
}
|
|
74
106
|
case 'plugin':
|
|
75
107
|
return await pluginManager.executePlugin(action.pluginName, action.target);
|
|
76
108
|
case 'system_automation':
|
|
@@ -80,10 +112,27 @@ async function executeAction(action, options = {}) {
|
|
|
80
112
|
}
|
|
81
113
|
}
|
|
82
114
|
|
|
115
|
+
async function handleSystemInfo(target = '') {
|
|
116
|
+
const query = String(target || '').trim();
|
|
117
|
+
if (query) {
|
|
118
|
+
const weather = await getWeather(query);
|
|
119
|
+
return JSON.stringify({
|
|
120
|
+
type: 'weather',
|
|
121
|
+
target: query,
|
|
122
|
+
...weather
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
return JSON.stringify({
|
|
126
|
+
type: 'system_info',
|
|
127
|
+
data: getSystemInfo()
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
83
131
|
async function executeFindPath(action) {
|
|
84
132
|
const result = findPath(action.target, {
|
|
85
133
|
type: action.pathType,
|
|
86
|
-
maxResults: 10
|
|
134
|
+
maxResults: 10,
|
|
135
|
+
roots: safetyManager.getAllowedRoots('read')
|
|
87
136
|
});
|
|
88
137
|
if (!result.success) {
|
|
89
138
|
return result.message;
|
|
@@ -126,4 +175,4 @@ async function handleSystemAutomation(target) {
|
|
|
126
175
|
}
|
|
127
176
|
}
|
|
128
177
|
|
|
129
|
-
module.exports = { executeAction, handleSystemAutomation };
|
|
178
|
+
module.exports = { executeAction, handleSystemAutomation, handleSystemInfo };
|
|
@@ -19,21 +19,29 @@ if (!fs.existsSync(CONFIG_DIR)) {
|
|
|
19
19
|
|
|
20
20
|
const CHAT_HISTORY_PATH = path.join(CONFIG_DIR, 'mint-chat-history.json');
|
|
21
21
|
|
|
22
|
-
// Migration Logic: Consolidate from
|
|
22
|
+
// Migration Logic: Consolidate from various legacy locations to ~/.config/mint/
|
|
23
23
|
if (!fs.existsSync(CHAT_HISTORY_PATH)) {
|
|
24
24
|
const electronUserData = app && app.getPath ? path.join(app.getPath('userData'), 'mint-chat-history.json') : null;
|
|
25
|
-
const
|
|
25
|
+
const legacyDotMint = path.join(MINT_DIR, 'mint-chat-history.json');
|
|
26
|
+
// Legacy: file was written to the project root (CWD) before v1.5.2
|
|
27
|
+
const legacyProjectRoot = path.join(process.cwd(), 'mint-chat-history.json');
|
|
26
28
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
29
|
+
const candidates = [
|
|
30
|
+
electronUserData,
|
|
31
|
+
legacyDotMint,
|
|
32
|
+
legacyProjectRoot
|
|
33
|
+
].filter(Boolean);
|
|
34
|
+
|
|
35
|
+
for (const candidate of candidates) {
|
|
36
|
+
if (candidate !== CHAT_HISTORY_PATH && fs.existsSync(candidate)) {
|
|
37
|
+
try {
|
|
38
|
+
fs.copyFileSync(candidate, CHAT_HISTORY_PATH);
|
|
39
|
+
console.log(`[History] Migrated chat history from ${candidate}`);
|
|
40
|
+
} catch (e) {
|
|
41
|
+
console.error('[History] Migration failed:', e);
|
|
42
|
+
}
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
37
45
|
}
|
|
38
46
|
}
|
|
39
47
|
|
|
@@ -99,7 +99,37 @@ const DEFAULT_CONFIG = {
|
|
|
99
99
|
enableAgentCollaboration: false,
|
|
100
100
|
enableAutoUpdate: true,
|
|
101
101
|
autoUpdateCheckIntervalHours: 24,
|
|
102
|
-
lastUpdateCheckAt: ''
|
|
102
|
+
lastUpdateCheckAt: '',
|
|
103
|
+
safetyEnabled: true,
|
|
104
|
+
sandboxMode: 'prefer', // off | prefer | enforce
|
|
105
|
+
sandboxCommand: process.platform === 'darwin' ? 'sandbox-exec' : process.platform === 'linux' ? 'bwrap' : '',
|
|
106
|
+
allowedReadPaths: [
|
|
107
|
+
os.homedir(),
|
|
108
|
+
process.cwd(),
|
|
109
|
+
path.join(os.homedir(), 'Desktop'),
|
|
110
|
+
path.join(os.homedir(), 'Documents'),
|
|
111
|
+
path.join(os.homedir(), 'Downloads'),
|
|
112
|
+
path.join(os.homedir(), 'Pictures'),
|
|
113
|
+
path.join(os.homedir(), 'Music'),
|
|
114
|
+
path.join(os.homedir(), 'Videos')
|
|
115
|
+
],
|
|
116
|
+
allowedWritePaths: [
|
|
117
|
+
os.homedir(),
|
|
118
|
+
process.cwd(),
|
|
119
|
+
path.join(os.homedir(), 'Desktop'),
|
|
120
|
+
path.join(os.homedir(), 'Documents'),
|
|
121
|
+
path.join(os.homedir(), 'Downloads'),
|
|
122
|
+
path.join(os.homedir(), 'Pictures'),
|
|
123
|
+
path.join(os.homedir(), 'Music'),
|
|
124
|
+
path.join(os.homedir(), 'Videos')
|
|
125
|
+
],
|
|
126
|
+
blockedPaths: [
|
|
127
|
+
path.join(os.homedir(), '.ssh'),
|
|
128
|
+
path.join(os.homedir(), '.gnupg'),
|
|
129
|
+
path.join(os.homedir(), '.config', 'mint', 'mint-config.json'),
|
|
130
|
+
path.join(os.homedir(), '.mint', 'mint-config.json')
|
|
131
|
+
],
|
|
132
|
+
blockedFileNames: ['.env', 'id_rsa', 'id_ed25519']
|
|
103
133
|
};
|
|
104
134
|
|
|
105
135
|
|