@pheem49/mint 1.5.5 → 1.6.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.
Files changed (222) hide show
  1. package/.codex +0 -0
  2. package/.github/FUNDING.yml +2 -0
  3. package/.github/workflows/ci.yml +45 -0
  4. package/.github/workflows/release.yml +79 -0
  5. package/Cargo.lock +5792 -0
  6. package/Cargo.toml +32 -0
  7. package/README.md +387 -353
  8. package/assets/icon.png +0 -0
  9. package/bin/mint +0 -0
  10. package/crates/mint-cli/Cargo.toml +23 -0
  11. package/crates/mint-cli/src/agent.rs +851 -0
  12. package/crates/mint-cli/src/gmail.rs +216 -0
  13. package/crates/mint-cli/src/image.rs +142 -0
  14. package/crates/mint-cli/src/main.rs +2837 -0
  15. package/crates/mint-cli/src/mcp.rs +63 -0
  16. package/crates/mint-cli/src/onboard.rs +1149 -0
  17. package/crates/mint-cli/src/setup.rs +390 -0
  18. package/crates/mint-cli/src/skills.rs +8 -0
  19. package/crates/mint-cli/src/updater.rs +279 -0
  20. package/crates/mint-core/Cargo.toml +22 -0
  21. package/crates/mint-core/src/agent_loop.rs +94 -0
  22. package/crates/mint-core/src/api_server.rs +991 -0
  23. package/crates/mint-core/src/channels.rs +248 -0
  24. package/crates/mint-core/src/chat.rs +895 -0
  25. package/crates/mint-core/src/code_tools.rs +729 -0
  26. package/crates/mint-core/src/config.rs +368 -0
  27. package/crates/mint-core/src/files.rs +159 -0
  28. package/crates/mint-core/src/knowledge.rs +541 -0
  29. package/crates/mint-core/src/lib.rs +84 -0
  30. package/crates/mint-core/src/mcp.rs +273 -0
  31. package/crates/mint-core/src/memory.rs +673 -0
  32. package/crates/mint-core/src/orchestration.rs +2157 -0
  33. package/crates/mint-core/src/pictures.rs +314 -0
  34. package/crates/mint-core/src/plugins.rs +727 -0
  35. package/crates/mint-core/src/safety.rs +416 -0
  36. package/crates/mint-core/src/semantic.rs +254 -0
  37. package/crates/mint-core/src/shell.rs +317 -0
  38. package/crates/mint-core/src/skills.rs +71 -0
  39. package/crates/mint-core/src/symbols.rs +157 -0
  40. package/crates/mint-core/src/tasks.rs +308 -0
  41. package/crates/mint-core/src/tts.rs +92 -0
  42. package/crates/mint-core/src/weather.rs +93 -0
  43. package/crates/mint-core/src/web_search.rs +200 -0
  44. package/crates/mint-core/src/workflows.rs +81 -0
  45. package/crates/mint-core/tests/mcp_stdio.rs +45 -0
  46. package/crates/mint-core/tests/memory_persistence.rs +172 -0
  47. package/crates/mint-core/tests/pictures_storage.rs +14 -0
  48. package/crates/mint-core/tests/task_lifecycle.rs +87 -0
  49. package/package.json +35 -99
  50. package/src/bin/index.js +16 -0
  51. package/src/renderer/index-web.html +17 -0
  52. package/src/renderer/index.html +17 -0
  53. package/src/renderer/public/Live2DCubismCore.js +9 -0
  54. package/src/renderer/public/assets/icon.png +0 -0
  55. package/src/renderer/public/models/Shiroko_Model/Shiroko/Shiroko_Core/shiroko.model3.json +36 -0
  56. package/src/renderer/src/App.tsx +33 -0
  57. package/src/renderer/src/calculator.ts +47 -0
  58. package/src/renderer/src/components/ChatPanel.tsx +1598 -0
  59. package/src/renderer/src/components/DashboardSidebar.tsx +358 -0
  60. package/src/renderer/src/components/Live2DStage.tsx +374 -0
  61. package/src/renderer/src/components/MintDashboard.tsx +950 -0
  62. package/src/renderer/src/components/ModelPanel.tsx +154 -0
  63. package/src/renderer/src/components/PicturesLibrary.tsx +46 -0
  64. package/src/renderer/src/components/ProactiveGlow.tsx +19 -0
  65. package/src/renderer/src/components/ScreenPicker.tsx +579 -0
  66. package/src/renderer/src/components/SettingsWindow.tsx +1467 -0
  67. package/src/renderer/src/components/SpotlightWindow.tsx +280 -0
  68. package/src/renderer/src/components/WidgetWindow.tsx +36 -0
  69. package/src/renderer/src/components/WorkspacePanel.tsx +268 -0
  70. package/src/{UI → renderer/src/css}/settings.css +69 -16
  71. package/src/renderer/src/css/spotlight.css +113 -0
  72. package/src/renderer/src/css/styles.css +3722 -0
  73. package/src/renderer/src/css/widget.css +185 -0
  74. package/src/renderer/src/env.d.ts +116 -0
  75. package/src/renderer/src/index.css +379 -0
  76. package/src/renderer/src/main.tsx +13 -0
  77. package/src/renderer/src/tauri.ts +996 -0
  78. package/src/renderer/src-web/App.tsx +25 -0
  79. package/src/renderer/src-web/calculator.ts +47 -0
  80. package/src/renderer/src-web/components/ChatPanel.tsx +1662 -0
  81. package/src/renderer/src-web/components/DashboardSidebar.tsx +242 -0
  82. package/src/renderer/src-web/components/MintDashboard.tsx +763 -0
  83. package/src/renderer/src-web/components/PicturesLibrary.tsx +73 -0
  84. package/src/renderer/src-web/components/SettingsWindow.tsx +1500 -0
  85. package/src/renderer/src-web/css/settings.css +1100 -0
  86. package/src/{UI → renderer/src-web/css}/spotlight.css +4 -4
  87. package/src/{UI → renderer/src-web/css}/styles.css +1055 -159
  88. package/src/{UI → renderer/src-web/css}/widget.css +2 -2
  89. package/src/renderer/src-web/env.d.ts +107 -0
  90. package/src/renderer/src-web/index.css +379 -0
  91. package/src/renderer/src-web/main.tsx +13 -0
  92. package/src/renderer/src-web/tauri.ts +983 -0
  93. package/tsconfig.json +30 -0
  94. package/vite.config.ts +33 -0
  95. package/vite.config.web.ts +51 -0
  96. package/GUIDE_TH.md +0 -125
  97. package/assets/Agent_Mint.png +0 -0
  98. package/assets/CLI_Screen.png +0 -0
  99. package/assets/Settings.png +0 -0
  100. package/benchmark_ai.js +0 -71
  101. package/install.ps1 +0 -64
  102. package/install.sh +0 -54
  103. package/main.js +0 -139
  104. package/mint-cli-logic.js +0 -3
  105. package/mint-cli.js +0 -410
  106. package/models/Shiroko_Model/Shiroko/Shiroko_Core//351/235/242/351/245/2740.model3.json +0 -47
  107. 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 +0 -23
  108. package/preload-picker.js +0 -11
  109. package/preload-settings.js +0 -11
  110. package/preload.js +0 -41
  111. package/scripts/install_linux_desktop_entry.js +0 -48
  112. package/src/AI_Brain/Gemini_API.js +0 -813
  113. package/src/AI_Brain/agent_orchestrator.js +0 -73
  114. package/src/AI_Brain/autonomous_brain.js +0 -179
  115. package/src/AI_Brain/behavior_memory.js +0 -135
  116. package/src/AI_Brain/headless_agent.js +0 -143
  117. package/src/AI_Brain/knowledge_base.js +0 -349
  118. package/src/AI_Brain/memory_store.js +0 -662
  119. package/src/AI_Brain/proactive_engine.js +0 -172
  120. package/src/AI_Brain/provider_adapter.js +0 -365
  121. package/src/Automation_Layer/browser_automation.js +0 -149
  122. package/src/Automation_Layer/file_operations.js +0 -286
  123. package/src/Automation_Layer/open_app.js +0 -85
  124. package/src/Automation_Layer/open_website.js +0 -38
  125. package/src/CLI/approval_handler.js +0 -47
  126. package/src/CLI/chat_router.js +0 -247
  127. package/src/CLI/chat_ui.js +0 -1159
  128. package/src/CLI/cli_colors.js +0 -115
  129. package/src/CLI/cli_formatters.js +0 -94
  130. package/src/CLI/code_agent.js +0 -1667
  131. package/src/CLI/code_session_memory.js +0 -62
  132. package/src/CLI/gmail_auth.js +0 -210
  133. package/src/CLI/image_input.js +0 -90
  134. package/src/CLI/intent_detectors.js +0 -181
  135. package/src/CLI/interactive_chat.js +0 -658
  136. package/src/CLI/list_features.js +0 -64
  137. package/src/CLI/onboarding.js +0 -416
  138. package/src/CLI/repo_summarizer.js +0 -282
  139. package/src/CLI/semantic_code_search.js +0 -312
  140. package/src/CLI/skill_manager.js +0 -41
  141. package/src/CLI/slash_command_handler.js +0 -418
  142. package/src/CLI/symbol_indexer.js +0 -231
  143. package/src/CLI/updater.js +0 -230
  144. package/src/CLI/workspace_manager.js +0 -90
  145. package/src/Channels/brave_search_bridge.js +0 -35
  146. package/src/Channels/discord_bridge.js +0 -66
  147. package/src/Channels/google_search_bridge.js +0 -38
  148. package/src/Channels/line_bridge.js +0 -60
  149. package/src/Channels/slack_bridge.js +0 -48
  150. package/src/Channels/telegram_bridge.js +0 -41
  151. package/src/Channels/whatsapp_bridge.js +0 -57
  152. package/src/Command_Parser/parser.js +0 -45
  153. package/src/Plugins/dev_tools.js +0 -41
  154. package/src/Plugins/discord.js +0 -20
  155. package/src/Plugins/docker.js +0 -47
  156. package/src/Plugins/gmail.js +0 -251
  157. package/src/Plugins/google_calendar.js +0 -252
  158. package/src/Plugins/mcp_manager.js +0 -95
  159. package/src/Plugins/notion.js +0 -256
  160. package/src/Plugins/obsidian.js +0 -54
  161. package/src/Plugins/plugin_manager.js +0 -81
  162. package/src/Plugins/spotify.js +0 -173
  163. package/src/Plugins/system_metrics.js +0 -31
  164. package/src/Plugins/system_monitor.js +0 -72
  165. package/src/System/action_executor.js +0 -178
  166. package/src/System/bridge_manager.js +0 -76
  167. package/src/System/chat_history_manager.js +0 -83
  168. package/src/System/config_manager.js +0 -194
  169. package/src/System/custom_workflows.js +0 -163
  170. package/src/System/daemon_manager.js +0 -67
  171. package/src/System/google_tts_urls.js +0 -51
  172. package/src/System/granular_automation.js +0 -157
  173. package/src/System/ipc_handlers.js +0 -332
  174. package/src/System/notifications.js +0 -23
  175. package/src/System/optional_require.js +0 -23
  176. package/src/System/picture_store.js +0 -109
  177. package/src/System/proactive_loop.js +0 -153
  178. package/src/System/safety_manager.js +0 -273
  179. package/src/System/sandbox_runner.js +0 -182
  180. package/src/System/screen_capture.js +0 -175
  181. package/src/System/smart_context.js +0 -227
  182. package/src/System/system_automation.js +0 -162
  183. package/src/System/system_events.js +0 -79
  184. package/src/System/system_info.js +0 -125
  185. package/src/System/task_manager.js +0 -222
  186. package/src/System/tool_registry.js +0 -293
  187. package/src/System/window_manager.js +0 -220
  188. package/src/UI/floating.css +0 -80
  189. package/src/UI/floating.html +0 -17
  190. package/src/UI/floating.js +0 -67
  191. package/src/UI/live2d_manager.js +0 -600
  192. package/src/UI/preload-floating.js +0 -7
  193. package/src/UI/preload-spotlight.js +0 -11
  194. package/src/UI/preload-widget.js +0 -5
  195. package/src/UI/proactive-glow.html +0 -42
  196. package/src/UI/renderer.js +0 -2127
  197. package/src/UI/screenPicker.html +0 -214
  198. package/src/UI/screenPicker.js +0 -262
  199. package/src/UI/settings.html +0 -577
  200. package/src/UI/settings.js +0 -770
  201. package/src/UI/spotlight.html +0 -23
  202. package/src/UI/spotlight.js +0 -185
  203. package/src/UI/widget.html +0 -29
  204. package/src/UI/widget.js +0 -10
  205. /package/{models → src/renderer/public/models}/Shiroko_Model/Shiroko/Shiroko_Core/72d86db84cfa9730b894c241fd24c0db.png +0 -0
  206. /package/{models/Shiroko_Model/Shiroko/Shiroko_Core//345/233/264/350/243/231.exp3.json" → src/renderer/public/models/Shiroko_Model/Shiroko/Shiroko_Core/apron.exp3.json} +0 -0
  207. /package/{models/Shiroko_Model/Shiroko/Shiroko_Core//347/214/253/345/222/252/346/273/244/351/225/234.exp3.json" → src/renderer/public/models/Shiroko_Model/Shiroko/Shiroko_Core/catfilter.exp3.json} +0 -0
  208. /package/{models/Shiroko_Model/Shiroko/Shiroko_Core//347/202/271/344/270/200/344/270/213.exp3.json" → src/renderer/public/models/Shiroko_Model/Shiroko/Shiroko_Core/click.exp3.json} +0 -0
  209. /package/{models/Shiroko_Model/Shiroko/Shiroko_Core//345/221/206/347/214/253.exp3.json" → src/renderer/public/models/Shiroko_Model/Shiroko/Shiroko_Core/dazed.exp3.json} +0 -0
  210. /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" → src/renderer/public/models/Shiroko_Model/Shiroko/Shiroko_Core/dazedeyes.exp3.json} +0 -0
  211. /package/{models/Shiroko_Model/Shiroko/Shiroko_Core//347/234/274/351/225/234.exp3.json" → src/renderer/public/models/Shiroko_Model/Shiroko/Shiroko_Core/glasses.exp3.json} +0 -0
  212. /package/{models → src/renderer/public/models}/Shiroko_Model/Shiroko/Shiroko_Core/items_pinned_to_model.json +0 -0
  213. /package/{models/Shiroko_Model/Shiroko/Shiroko_Core//346/213/277/347/254/224.exp3.json" → src/renderer/public/models/Shiroko_Model/Shiroko/Shiroko_Core/pen.exp3.json} +0 -0
  214. /package/{models/Shiroko_Model/Shiroko/Shiroko_Core//346/213/215/347/205/247.exp3.json" → src/renderer/public/models/Shiroko_Model/Shiroko/Shiroko_Core/photo.exp3.json} +0 -0
  215. /package/{models/Shiroko_Model/Shiroko/Shiroko_Core//351/235/242/351/245/2740.4096/texture_00.png" → src/renderer/public/models/Shiroko_Model/Shiroko/Shiroko_Core/shiroko.4096/texture_00.png} +0 -0
  216. /package/{models/Shiroko_Model/Shiroko/Shiroko_Core//351/235/242/351/245/2740.4096/texture_01.png" → src/renderer/public/models/Shiroko_Model/Shiroko/Shiroko_Core/shiroko.4096/texture_01.png} +0 -0
  217. /package/{models/Shiroko_Model/Shiroko/Shiroko_Core//351/235/242/351/245/2740.4096/texture_02.png" → src/renderer/public/models/Shiroko_Model/Shiroko/Shiroko_Core/shiroko.4096/texture_02.png} +0 -0
  218. /package/{models/Shiroko_Model/Shiroko/Shiroko_Core//351/235/242/351/245/2740.4096/texture_03.png" → src/renderer/public/models/Shiroko_Model/Shiroko/Shiroko_Core/shiroko.4096/texture_03.png} +0 -0
  219. /package/{models/Shiroko_Model/Shiroko/Shiroko_Core//351/235/242/351/245/2740.cdi3.json" → src/renderer/public/models/Shiroko_Model/Shiroko/Shiroko_Core/shiroko.cdi3.json} +0 -0
  220. /package/{models/Shiroko_Model/Shiroko/Shiroko_Core//351/235/242/351/245/2740.moc3" → src/renderer/public/models/Shiroko_Model/Shiroko/Shiroko_Core/shiroko.moc3} +0 -0
  221. /package/{models/Shiroko_Model/Shiroko/Shiroko_Core//351/235/242/351/245/2740.physics3.json" → src/renderer/public/models/Shiroko_Model/Shiroko/Shiroko_Core/shiroko.physics3.json} +0 -0
  222. /package/{models/Shiroko_Model/Shiroko/Shiroko_Core//351/235/242/351/245/2740.vtube.json" → src/renderer/public/models/Shiroko_Model/Shiroko/Shiroko_Core/shiroko.vtube.json} +0 -0
@@ -1,31 +0,0 @@
1
- const os = require('os');
2
- const { getSystemInfo } = require('../System/system_info');
3
-
4
- /**
5
- * System Metrics Plugin — Provides real-time hardware stats to Gemini
6
- */
7
- module.exports = {
8
- name: 'system_metrics',
9
- description: 'Get real-time system metrics like CPU usage, RAM, and uptime. Instruction can be "all", "ram", "cpu", or "uptime".',
10
-
11
- async execute(instruction) {
12
- const info = getSystemInfo();
13
- const uptimeMin = Math.floor(os.uptime() / 60);
14
- const uptimeHours = (uptimeMin / 60).toFixed(1);
15
-
16
- const inst = (instruction || 'all').toLowerCase();
17
-
18
- if (inst.includes('ram')) {
19
- return `ความจำเครื่อง (RAM): ใช้ไป ${info.ram.used} จากทั้งหมด ${info.ram.total} (${info.ram.percent})`;
20
- }
21
- if (inst.includes('cpu')) {
22
- return `หน่วยประมวลผล (CPU): ${info.cpu.model} มีทั้งหมด ${info.cpu.cores} คอร์`;
23
- }
24
- if (inst.includes('uptime')) {
25
- return `เปิดเครื่องมาแล้ว: ${uptimeMin} นาที (${uptimeHours} ชั่วโมง)`;
26
- }
27
-
28
- // Default: Return basic summary in Thai for Mint's personality
29
- return `สรุปสถานะระบบ: RAM ใช้ไป ${info.ram.percent}, CPU ${info.cpu.cores} Cores, เปิดเครื่องมาแล้ว ${uptimeMin} นาทีค่ะ ✨`;
30
- }
31
- };
@@ -1,72 +0,0 @@
1
- /**
2
- * Mint System Monitor Plugin
3
- * --------------------------
4
- * Provides real-time system statistics for the host machine.
5
- * Uses standard Linux commands (uptime, free, df) for lightweight monitoring.
6
- */
7
-
8
- const { exec } = require('child_process');
9
- const { promisify } = require('util');
10
- const execAsync = promisify(exec);
11
- const os = require('os');
12
-
13
- async function getStats() {
14
- try {
15
- const [uptime, free, df] = await Promise.all([
16
- execAsync('uptime -p'),
17
- execAsync('free -h'),
18
- execAsync('df -h / --output=pcent,avail')
19
- ]);
20
-
21
- // Parse Memory
22
- const memLines = free.stdout.split('\n');
23
- const memLine = memLines.find(l => l.startsWith('Mem:')) || '';
24
- const memParts = memLine.split(/\s+/).filter(Boolean);
25
- const memUsed = memParts[2] || 'Unknown';
26
- const memTotal = memParts[1] || 'Unknown';
27
-
28
- // Parse Disk
29
- const diskLines = df.stdout.trim().split('\n');
30
- const diskLine = diskLines[1] || '';
31
- const [diskPercent, diskAvail] = diskLine.trim().split(/\s+/);
32
-
33
- const cpuLoad = os.loadavg()[0].toFixed(2);
34
- const cpuCores = os.cpus().length;
35
-
36
- let report = `📊 **System Health Report**\n`;
37
- report += `⏱️ **Uptime:** ${uptime.stdout.trim()}\n`;
38
- report += `💻 **CPU Load:** ${cpuLoad} (on ${cpuCores} cores)\n`;
39
- report += `🧠 **Memory:** ${memUsed} / ${memTotal} used\n`;
40
- report += `💽 **Disk (/):** ${diskAvail} available (${diskPercent} full)`;
41
-
42
- return report;
43
- } catch (err) {
44
- return `❌ Error fetching system stats: ${err.message}`;
45
- }
46
- }
47
-
48
- module.exports = {
49
- name: 'system_monitor',
50
- description: 'Provides system statistics like CPU load, memory usage, disk space, and uptime. Target can be "stats", "cpu", "memory", or "disk".',
51
-
52
- async execute(target) {
53
- const cmd = (target || 'stats').toLowerCase().trim();
54
-
55
- switch (cmd) {
56
- case 'stats':
57
- case 'health':
58
- return await getStats();
59
- case 'cpu':
60
- return `💻 **CPU Load (1m):** ${os.loadavg()[0].toFixed(2)}\nCores: ${os.cpus().length}\nModel: ${os.cpus()[0].model}`;
61
- case 'memory':
62
- case 'ram':
63
- const { stdout: mem } = await execAsync('free -h');
64
- return `🧠 **Memory Status:**\n\`\`\`\n${mem}\`\`\``;
65
- case 'disk':
66
- const { stdout: disk } = await execAsync('df -h /');
67
- return `💽 **Disk Status:**\n\`\`\`\n${disk}\`\`\``;
68
- default:
69
- return await getStats();
70
- }
71
- }
72
- };
@@ -1,178 +0,0 @@
1
- let electronClipboard = null;
2
- try {
3
- ({ clipboard: electronClipboard } = require('electron'));
4
- } catch (_) {
5
- electronClipboard = {
6
- writeText: () => {}
7
- };
8
- }
9
- const { openApp } = require('../Automation_Layer/open_app');
10
- const { openWebsite, openSearch } = require('../Automation_Layer/open_website');
11
- const { performWebAutomation } = require('../Automation_Layer/browser_automation');
12
- const { createFolder, openFile, deleteFile, findPath } = require('../Automation_Layer/file_operations');
13
- const { indexFile, indexFolder } = require('../AI_Brain/knowledge_base');
14
- const { getSystemInfo, getWeather } = require('./system_info');
15
- const pluginManager = require('../Plugins/plugin_manager');
16
- const mcpManager = require('../Plugins/mcp_manager');
17
- const SystemAutomation = require('./system_automation');
18
- const safetyManager = require('./safety_manager');
19
- const toolRegistry = require('./tool_registry');
20
- const os = require('os');
21
- const path = require('path');
22
-
23
- async function executeAction(action, options = {}) {
24
- if (process.env.MINT_DEBUG === '1') {
25
- console.log("Executing action:", action);
26
- }
27
- toolRegistry.validateToolInput(action.type, action);
28
- const clipboard = options.clipboard || electronClipboard;
29
- const safety = safetyManager.assertActionAllowed(action, {
30
- allowApproval: options.allowApproval === true,
31
- allowDangerous: options.allowDangerous === true
32
- });
33
- safetyManager.appendActionLog({
34
- source: options.source || 'action_executor',
35
- action: action.type,
36
- target: action.target || action.path || '',
37
- tier: safety.tier,
38
- approved: options.allowApproval === true || options.allowDangerous === true || safety.tier === safetyManager.TIERS.SAFE
39
- });
40
-
41
- switch (action.type) {
42
- case 'open_url':
43
- openWebsite(action.target);
44
- break;
45
- case 'search':
46
- openSearch(action.target);
47
- break;
48
- case 'open_app':
49
- openApp(action.target);
50
- break;
51
- case 'web_automation':
52
- return await performWebAutomation(action.target);
53
- case 'create_folder':
54
- safetyManager.assertPathCapability(action.target, 'write', {
55
- defaultBase: path.join(os.homedir(), 'Desktop')
56
- });
57
- createFolder(action.target);
58
- break;
59
- case 'open_file': {
60
- safetyManager.assertPathCapability(action.target, 'read');
61
- const fileRes = await openFile(action.target);
62
- return fileRes || `Successfully opened file: ${action.target} ✅`;
63
- }
64
- case 'open_folder': {
65
- safetyManager.assertPathCapability(action.target, 'read');
66
- const folderRes = await openFile(action.target);
67
- return folderRes || `Successfully opened folder: ${action.target} ✅`;
68
- }
69
- case 'delete_file':
70
- safetyManager.assertPathCapability(action.target, 'write');
71
- await deleteFile(action.target);
72
- break;
73
- case 'find_path':
74
- return await executeFindPath(action);
75
- case 'clipboard_write':
76
- clipboard.writeText(action.target);
77
- break;
78
- case 'learn_file':
79
- safetyManager.assertPathCapability(action.target, 'read');
80
- return await indexFile(action.target);
81
- case 'learn_folder':
82
- safetyManager.assertPathCapability(action.target, 'read');
83
- return await indexFolder(action.target);
84
- case 'system_info':
85
- return await handleSystemInfo(action.target);
86
- case 'mcp_tool': {
87
- const mcpResult = await mcpManager.callTool(action.server, action.target, action.args);
88
- return JSON.stringify(mcpResult.content);
89
- }
90
- case 'mouse_move': {
91
- const granularAutomation = require('./granular_automation');
92
- return await granularAutomation.mouseMove(action.x, action.y);
93
- }
94
- case 'mouse_click': {
95
- const granularAutomation = require('./granular_automation');
96
- return await granularAutomation.mouseClick(action.x, action.y, action.button || 1);
97
- }
98
- case 'type_text': {
99
- const granularAutomation = require('./granular_automation');
100
- return await granularAutomation.typeText(action.target);
101
- }
102
- case 'key_tap': {
103
- const granularAutomation = require('./granular_automation');
104
- return await granularAutomation.keyTap(action.target);
105
- }
106
- case 'plugin':
107
- return await pluginManager.executePlugin(action.pluginName, action.target);
108
- case 'system_automation':
109
- return await handleSystemAutomation(action.target);
110
- default:
111
- return undefined;
112
- }
113
- }
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
-
131
- async function executeFindPath(action) {
132
- const result = findPath(action.target, {
133
- type: action.pathType,
134
- maxResults: 10,
135
- roots: safetyManager.getAllowedRoots('read')
136
- });
137
- if (!result.success) {
138
- return result.message;
139
- }
140
-
141
- if (action.openAfter === true) {
142
- if (result.matches.length === 1) {
143
- const match = result.matches[0];
144
- const openResult = await openFile(match.path);
145
- return openResult || `Successfully found and opened ${match.type === 'dir' ? 'folder' : 'file'}: ${match.path} ✅`;
146
- }
147
- return `Found multiple matches for "${action.target}". Please be more specific:\n${result.matches.map(m => `- [${m.type}] ${m.path}`).join('\n')}`;
148
- }
149
-
150
- return `Found matches for "${action.target}":\n${result.matches.map(m => `- [${m.type}] ${m.path}`).join('\n')}`;
151
- }
152
-
153
- async function handleSystemAutomation(target) {
154
- const [cmd, value] = target.split(':');
155
- switch (cmd) {
156
- case 'volume':
157
- return await SystemAutomation.setVolume(parseInt(value));
158
- case 'mute':
159
- return await SystemAutomation.mute();
160
- case 'brightness':
161
- return await SystemAutomation.setBrightness(parseInt(value));
162
- case 'sleep':
163
- return await SystemAutomation.sleep();
164
- case 'restart':
165
- return await SystemAutomation.restart();
166
- case 'shutdown':
167
- return await SystemAutomation.shutdown();
168
- case 'minimize_all':
169
- return await SystemAutomation.minimizeAll();
170
- default:
171
- if (SystemAutomation[target]) {
172
- return await SystemAutomation[target]();
173
- }
174
- throw new Error(`Unknown system automation command: ${target}`);
175
- }
176
- }
177
-
178
- module.exports = { executeAction, handleSystemAutomation, handleSystemInfo };
@@ -1,76 +0,0 @@
1
- const { readConfig } = require('./config_manager');
2
- const path = require('path');
3
- const fs = require('fs');
4
-
5
- class BridgeManager {
6
- constructor() {
7
- this.bridges = new Map();
8
- this.channelsDir = path.join(__dirname, '..', 'Channels');
9
-
10
- if (!fs.existsSync(this.channelsDir)) {
11
- fs.mkdirSync(this.channelsDir, { recursive: true });
12
- }
13
- }
14
-
15
- async init() {
16
- const config = readConfig();
17
- console.log('[BridgeManager] Initializing messaging bridges...');
18
-
19
- // Load Discord Bridge
20
- if (config.enableDiscordBridge && config.discordBotToken) {
21
- await this.startBridge('discord', config.discordBotToken);
22
- }
23
-
24
- // Load Telegram Bridge
25
- if (config.enableTelegramBridge && config.telegramBotToken) {
26
- await this.startBridge('telegram', config.telegramBotToken);
27
- }
28
-
29
- // Load Slack Bridge
30
- if (config.enableSlackBridge && config.slackBotToken && config.slackAppToken) {
31
- await this.startBridge('slack', { botToken: config.slackBotToken, appToken: config.slackAppToken });
32
- }
33
-
34
- // Load LINE Bridge
35
- if (config.enableLineBridge && config.lineChannelAccessToken && config.lineChannelSecret) {
36
- await this.startBridge('line', { accessToken: config.lineChannelAccessToken, secret: config.lineChannelSecret, port: config.lineWebhookPort });
37
- }
38
-
39
- // Load WhatsApp Bridge
40
- if (config.enableWhatsappBridge) {
41
- await this.startBridge('whatsapp', null);
42
- }
43
- }
44
-
45
- async startBridge(type, credentials) {
46
- try {
47
- const bridgePath = path.join(this.channelsDir, `${type}_bridge.js`);
48
- if (!fs.existsSync(bridgePath)) {
49
- console.error(`[BridgeManager] Bridge file not found: ${bridgePath}`);
50
- return;
51
- }
52
-
53
- const BridgeClass = require(bridgePath);
54
- const bridge = new BridgeClass(credentials);
55
- await bridge.connect();
56
- this.bridges.set(type, bridge);
57
- console.log(`[BridgeManager] ${type.toUpperCase()} bridge connected successfully.`);
58
- } catch (err) {
59
- console.error(`[BridgeManager] Failed to start ${type} bridge:`, err.message);
60
- }
61
- }
62
-
63
- async shutdown() {
64
- for (const [type, bridge] of this.bridges.entries()) {
65
- try {
66
- await bridge.disconnect();
67
- console.log(`[BridgeManager] ${type.toUpperCase()} bridge disconnected.`);
68
- } catch (err) {
69
- console.error(`[BridgeManager] Error disconnecting ${type} bridge:`, err.message);
70
- }
71
- }
72
- this.bridges.clear();
73
- }
74
- }
75
-
76
- module.exports = new BridgeManager();
@@ -1,83 +0,0 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
- const os = require('os');
4
-
5
- let app;
6
- try {
7
- const electron = require('electron');
8
- app = electron.app;
9
- } catch (e) {
10
- app = null;
11
- }
12
-
13
- const CONFIG_DIR = path.join(os.homedir(), '.config', 'mint');
14
- const MINT_DIR = path.join(os.homedir(), '.mint');
15
-
16
- if (!fs.existsSync(CONFIG_DIR)) {
17
- fs.mkdirSync(CONFIG_DIR, { recursive: true });
18
- }
19
-
20
- const CHAT_HISTORY_PATH = path.join(CONFIG_DIR, 'mint-chat-history.json');
21
-
22
- // Migration Logic: Consolidate from various legacy locations to ~/.config/mint/
23
- if (!fs.existsSync(CHAT_HISTORY_PATH)) {
24
- const electronUserData = app && app.getPath ? path.join(app.getPath('userData'), 'mint-chat-history.json') : null;
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');
28
-
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
- }
45
- }
46
- }
47
-
48
- function readChatHistory() {
49
- try {
50
- if (!fs.existsSync(CHAT_HISTORY_PATH)) {
51
- return [];
52
- }
53
-
54
- const raw = fs.readFileSync(CHAT_HISTORY_PATH, 'utf-8');
55
- const parsed = JSON.parse(raw);
56
- return Array.isArray(parsed) ? parsed : [];
57
- } catch (err) {
58
- console.error('readChatHistory error:', err);
59
- return [];
60
- }
61
- }
62
-
63
- function writeChatHistory(history) {
64
- try {
65
- const safeHistory = Array.isArray(history) ? history : [];
66
- fs.writeFileSync(CHAT_HISTORY_PATH, JSON.stringify(safeHistory, null, 2), 'utf-8');
67
- return { success: true };
68
- } catch (err) {
69
- console.error('writeChatHistory error:', err);
70
- return { success: false, message: err.message };
71
- }
72
- }
73
-
74
- function clearChatHistory() {
75
- return writeChatHistory([]);
76
- }
77
-
78
- module.exports = {
79
- CHAT_HISTORY_PATH,
80
- readChatHistory,
81
- writeChatHistory,
82
- clearChatHistory
83
- };
@@ -1,194 +0,0 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
- const os = require('os');
4
-
5
- let app;
6
- try {
7
- const electron = require('electron');
8
- app = electron.app;
9
- } catch (e) {
10
- app = null;
11
- }
12
-
13
- const CONFIG_DIR = path.join(os.homedir(), '.config', 'mint');
14
- const LEGACY_DIR = path.join(os.homedir(), '.mint');
15
-
16
- if (!fs.existsSync(CONFIG_DIR)) {
17
- fs.mkdirSync(CONFIG_DIR, { recursive: true });
18
- }
19
-
20
- // Migration: If old .mint exists but new .config/mint is empty, move files
21
- if (fs.existsSync(LEGACY_DIR) && fs.readdirSync(CONFIG_DIR).length === 0) {
22
- try {
23
- const files = fs.readdirSync(LEGACY_DIR);
24
- for (const file of files) {
25
- fs.copyFileSync(path.join(LEGACY_DIR, file), path.join(CONFIG_DIR, file));
26
- }
27
- console.log('[Config] Migrated settings from ~/.mint to ~/.config/mint');
28
- } catch (e) {
29
- console.error('[Config] Migration failed:', e);
30
- }
31
- }
32
-
33
- const CONFIG_PATH = path.join(CONFIG_DIR, 'mint-config.json');
34
-
35
- const DEFAULT_CONFIG = {
36
- theme: 'dark',
37
- accentColor: '#8b5cf6',
38
- systemTextColor: '#f8fafc',
39
- customBgStart: '#0f172a',
40
- customBgEnd: '#1e1b4b',
41
- customPanelBg: '#1e293b',
42
- glassBlur: 'blur(16px)',
43
- fontFamily: "'Outfit', sans-serif",
44
- fontSize: '15px',
45
- apiKey: '',
46
- geminiModel: 'gemini-2.5-flash',
47
- language: 'th-TH',
48
- assistantMode: 'chat',
49
- automationBrowser: 'chromium',
50
- proactiveInterval: 60, // seconds between screen captures
51
- proactiveCooldown: 120, // seconds minimum between actual suggestions
52
- aiProvider: 'gemini',
53
- ollamaModel: 'llama3:latest',
54
- enableVoiceReply: true,
55
- enableCustomWorkflows: true,
56
- ttsProvider: 'google',
57
- ttsVolume: 1.0,
58
- ttsSpeed: 1.0,
59
- ttsPitch: 1.0,
60
- pluginCalendarEnabled: false,
61
- pluginGmailEnabled: false,
62
- pluginNotionEnabled: false,
63
- pluginDiscordEnabled: false,
64
- showDesktopWidget: true,
65
- mcpServers: {},
66
- telegramBotToken: '',
67
- enableTelegramBridge: false,
68
- discordBotToken: '',
69
- enableDiscordBridge: false,
70
- slackBotToken: '',
71
- slackAppToken: '',
72
- enableSlackBridge: false,
73
- lineChannelAccessToken: '',
74
- lineChannelSecret: '',
75
- enableLineBridge: false,
76
- lineWebhookPort: 3000,
77
- enableWhatsappBridge: false,
78
- googleSearchApiKey: '',
79
- googleSearchCx: '',
80
- googleCalendarClientId: '',
81
- googleCalendarClientSecret: '',
82
- googleCalendarRefreshToken: '',
83
- googleCalendarId: 'primary',
84
- gmailClientId: '',
85
- gmailClientSecret: '',
86
- gmailRefreshToken: '',
87
- gmailUserId: 'me',
88
- notionApiKey: '',
89
- notionDatabaseId: '',
90
- notionPageId: '',
91
- notionTitleProperty: 'Name',
92
- braveSearchApiKey: '',
93
- anthropicApiKey: '',
94
-
95
- openaiApiKey: '',
96
- hfApiKey: '',
97
- anthropicModel: 'claude-3-5-sonnet-latest',
98
- openaiModel: 'gpt-4o',
99
- hfModel: 'meta-llama/Meta-Llama-3-8B-Instruct',
100
- localApiBaseUrl: '',
101
- localModelName: 'local-model',
102
- ollamaHost: '',
103
- enableAgentCollaboration: false,
104
- enableAutoUpdate: true,
105
- autoUpdateCheckIntervalHours: 24,
106
- lastUpdateCheckAt: '',
107
- safetyEnabled: true,
108
- sandboxMode: 'prefer', // off | prefer | enforce
109
- sandboxCommand: process.platform === 'darwin' ? 'sandbox-exec' : process.platform === 'linux' ? 'bwrap' : '',
110
- allowedReadPaths: [
111
- os.homedir(),
112
- process.cwd(),
113
- path.join(os.homedir(), 'Desktop'),
114
- path.join(os.homedir(), 'Documents'),
115
- path.join(os.homedir(), 'Downloads'),
116
- path.join(os.homedir(), 'Pictures'),
117
- path.join(os.homedir(), 'Music'),
118
- path.join(os.homedir(), 'Videos')
119
- ],
120
- allowedWritePaths: [
121
- os.homedir(),
122
- process.cwd(),
123
- path.join(os.homedir(), 'Desktop'),
124
- path.join(os.homedir(), 'Documents'),
125
- path.join(os.homedir(), 'Downloads'),
126
- path.join(os.homedir(), 'Pictures'),
127
- path.join(os.homedir(), 'Music'),
128
- path.join(os.homedir(), 'Videos')
129
- ],
130
- blockedPaths: [
131
- path.join(os.homedir(), '.ssh'),
132
- path.join(os.homedir(), '.gnupg'),
133
- path.join(os.homedir(), '.config', 'mint', 'mint-config.json'),
134
- path.join(os.homedir(), '.mint', 'mint-config.json')
135
- ],
136
- blockedFileNames: ['.env', 'id_rsa', 'id_ed25519']
137
- };
138
-
139
-
140
-
141
- function readConfig() {
142
- try {
143
- if (!fs.existsSync(CONFIG_PATH)) {
144
- writeConfig(DEFAULT_CONFIG);
145
- return DEFAULT_CONFIG;
146
- }
147
- const raw = fs.readFileSync(CONFIG_PATH, 'utf-8');
148
- return { ...DEFAULT_CONFIG, ...JSON.parse(raw) };
149
- } catch (err) {
150
- console.error('readConfig error:', err);
151
- return DEFAULT_CONFIG;
152
- }
153
- }
154
-
155
- function writeConfig(config) {
156
- try {
157
- fs.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2), 'utf-8');
158
- return { success: true };
159
- } catch (err) {
160
- console.error('writeConfig error:', err);
161
- return { success: false, message: err.message };
162
- }
163
- }
164
-
165
- function getAvailableProviders(config) {
166
- const providers = [];
167
- const cfg = config || readConfig();
168
-
169
- // Check which providers have API keys or URLs configured
170
- const anthropicKey = cfg.anthropicApiKey || process.env.ANTHROPIC_API_KEY;
171
- if (!isPlaceholder(anthropicKey)) providers.push('anthropic');
172
-
173
- const openaiKey = cfg.openaiApiKey || process.env.OPENAI_API_KEY;
174
- if (!isPlaceholder(openaiKey)) providers.push('openai');
175
-
176
- const geminiKey = cfg.apiKey || process.env.GEMINI_API_KEY;
177
- if (!isPlaceholder(geminiKey)) providers.push('gemini');
178
-
179
- const hfKey = cfg.hfApiKey || process.env.HF_API_KEY;
180
- if (!isPlaceholder(hfKey)) providers.push('huggingface');
181
-
182
- if (cfg.localApiBaseUrl && cfg.localApiBaseUrl.trim() !== '') providers.push('local_openai');
183
-
184
- // Always push ollama at the end since it's local
185
- providers.push('ollama');
186
-
187
- return providers;
188
- }
189
-
190
- function isPlaceholder(val) {
191
- return !val || val.startsWith('your_') || val.includes('key_here') || val.trim() === '';
192
- }
193
-
194
- module.exports = { readConfig, writeConfig, getAvailableProviders, isPlaceholder, CONFIG_PATH, CONFIG_DIR };