@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,163 +0,0 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
- const os = require('os');
4
- const { exec } = require('child_process');
5
-
6
- // Handle electron dependency safely
7
- let app, shell;
8
- try {
9
- const electron = require('electron');
10
- app = electron.app;
11
- shell = electron.shell;
12
- } catch (e) {
13
- app = null;
14
- shell = null;
15
- }
16
-
17
- function escapeRegExp(text) {
18
- return String(text).replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
19
- }
20
-
21
- class CustomWorkflows {
22
- constructor() {
23
- const configDir = path.join(os.homedir(), '.config', 'mint');
24
- this.configPath = path.join(configDir, 'workflows.json');
25
- this.workflows = [];
26
- this.lastTriggered = {};
27
- this.cooldownMs = 60 * 60 * 1000; // 1 hour cooldown per rule
28
- this.checkIntervalMs = 15000; // 15 seconds poll rate
29
- this.timer = null;
30
- this.webContents = null;
31
-
32
- if (!fs.existsSync(configDir)) {
33
- fs.mkdirSync(configDir, { recursive: true });
34
- }
35
-
36
- this.migrateConfig();
37
- this.ensureConfigExists();
38
- this.loadWorkflows();
39
- }
40
-
41
- migrateConfig() {
42
- if (!fs.existsSync(this.configPath) && app && app.getPath) {
43
- const electronPath = path.join(app.getPath('userData'), 'workflows.json');
44
- if (fs.existsSync(electronPath)) {
45
- try {
46
- fs.copyFileSync(electronPath, this.configPath);
47
- console.log('[CustomWorkflows] Migrated workflows from Electron userData');
48
- } catch (e) { console.error('[CustomWorkflows] Migration failed:', e); }
49
- }
50
- }
51
- }
52
-
53
- ensureConfigExists() {
54
- if (!fs.existsSync(this.configPath)) {
55
- const defaultWorkflows = [
56
- {
57
- id: "wf-1",
58
- name: "Check Mic on Zoom",
59
- trigger: { type: "process_running", processName: "zoom" },
60
- action: { type: "system_info", message: "Looks like you opened Zoom! Should I check your system resources? 📸", target: "" }
61
- },
62
- {
63
- id: "wf-2",
64
- name: "Coding Time",
65
- trigger: { type: "process_running", processName: "code" },
66
- action: { type: "open_app", target: "spotify", message: "Coding time! Want me to open Spotify for you? 🎧" }
67
- }
68
- ];
69
- fs.writeFileSync(this.configPath, JSON.stringify(defaultWorkflows, null, 4), 'utf-8');
70
- }
71
- }
72
-
73
- loadWorkflows() {
74
- try {
75
- const raw = fs.readFileSync(this.configPath, 'utf-8');
76
- this.workflows = JSON.parse(raw);
77
- console.log(`[CustomWorkflows] Loaded ${this.workflows.length} rules.`);
78
- } catch (e) {
79
- console.error("[CustomWorkflows] Failed to load workflows.json", e);
80
- this.workflows = [];
81
- }
82
- }
83
-
84
- startMonitoring(webContents) {
85
- this.webContents = webContents;
86
- if (this.timer) clearInterval(this.timer);
87
- this.timer = setInterval(() => this.checkProcesses(), this.checkIntervalMs);
88
- console.log('[CustomWorkflows] Started process monitoring.');
89
- }
90
-
91
- stopMonitoring() {
92
- if (this.timer) {
93
- clearInterval(this.timer);
94
- this.timer = null;
95
- }
96
- }
97
-
98
- openConfigFile() {
99
- // Try to open directly in VS Code since .json might natively open in a browser
100
- exec(`code "${this.configPath}"`, (err) => {
101
- if (err) {
102
- // Fallback: Open the folder containing the config file
103
- shell.showItemInFolder(this.configPath);
104
- console.log("[CustomWorkflows] Opened folder instead since VS Code wasn't found in PATH.");
105
- }
106
- });
107
- }
108
-
109
- async checkProcesses() {
110
- if (!this.workflows || this.workflows.length === 0) return;
111
-
112
- try {
113
- // Linux check using ps to get process names
114
- exec('ps -A -o comm=', (err, stdout) => {
115
- if (err) return;
116
- const runningProcesses = stdout.toLowerCase();
117
-
118
- for (const wf of this.workflows) {
119
- if (wf.trigger && wf.trigger.type === 'process_running' && wf.trigger.processName) {
120
- const targetName = wf.trigger.processName.toLowerCase();
121
- // simplistic exact-word match to avoid partial matches
122
- const regex = new RegExp(`^${escapeRegExp(targetName)}$`, 'm');
123
- const isRunning = regex.test(runningProcesses);
124
-
125
- if (isRunning) {
126
- const lastTime = this.lastTriggered[wf.id] || 0;
127
- const now = Date.now();
128
-
129
- // Cooldown mechanism
130
- if (now - lastTime > this.cooldownMs) {
131
- this.triggerWorkflow(wf);
132
- this.lastTriggered[wf.id] = now;
133
- }
134
- }
135
- }
136
- }
137
- });
138
- } catch (error) {
139
- console.error("Workflow check error:", error);
140
- }
141
- }
142
-
143
- triggerWorkflow(wf) {
144
- if (!this.webContents || this.webContents.isDestroyed()) return;
145
-
146
- console.log(`[CustomWorkflows] Triggering workflow: ${wf.name}`);
147
-
148
- const suggestion = {
149
- message: wf.action.message || `💡 Automation triggered: ${wf.name}`,
150
- suggestions: [
151
- { label: "Yes, please", action: wf.action },
152
- { label: "Dismiss", action: { type: "none" } }
153
- ]
154
- };
155
-
156
- this.webContents.send('proactive-suggestion', suggestion);
157
- }
158
- }
159
-
160
- const instance = new CustomWorkflows();
161
- instance._helpers = { escapeRegExp };
162
-
163
- module.exports = instance;
@@ -1,67 +0,0 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
- const { execSync } = require('child_process');
4
- const os = require('os');
5
-
6
- /**
7
- * Installs Mint as a systemd user service
8
- */
9
- async function installDaemon() {
10
- if (process.platform !== 'linux') {
11
- throw new Error('Daemon installation is currently only supported on Linux (systemd).');
12
- }
13
-
14
- const homeDir = os.homedir();
15
- const serviceDir = path.join(homeDir, '.config', 'systemd', 'user');
16
- const servicePath = path.join(serviceDir, 'mint-agent.service');
17
-
18
- // Create systemd user directory if it doesn't exist
19
- if (!fs.existsSync(serviceDir)) {
20
- fs.mkdirSync(serviceDir, { recursive: true });
21
- }
22
-
23
- const nodePath = execSync('which node').toString().trim() || '/usr/bin/node';
24
- const projectPath = path.resolve(__dirname, '../../');
25
- const cliPath = path.join(projectPath, 'mint-cli.js');
26
-
27
- const serviceContent = `[Unit]
28
- Description=Mint AI Background Agent
29
- After=network.target
30
-
31
- [Service]
32
- Type=simple
33
- WorkingDirectory=${projectPath}
34
- ExecStart=${nodePath} ${cliPath} agent
35
- Restart=always
36
- RestartSec=10
37
-
38
- [Install]
39
- WantedBy=default.target
40
- `;
41
-
42
- fs.writeFileSync(servicePath, serviceContent);
43
-
44
- try {
45
- console.log('[Daemon] Reloading systemd user daemon...');
46
- execSync('systemctl --user daemon-reload');
47
-
48
- console.log(`[Daemon] Enabling and starting mint-agent.service...`);
49
- execSync('systemctl --user enable mint-agent.service');
50
- execSync('systemctl --user start mint-agent.service');
51
-
52
- return `Mint Agent installed and started! Check logs with: journalctl --user -u mint-agent -f`;
53
- } catch (err) {
54
- throw new Error(`Failed to configure systemd: ${err.message}`);
55
- }
56
- }
57
-
58
- async function stopDaemon() {
59
- try {
60
- execSync('systemctl --user stop mint-agent.service');
61
- return "Daemon stopped.";
62
- } catch (err) {
63
- throw new Error(`Failed to stop daemon: ${err.message}`);
64
- }
65
- }
66
-
67
- module.exports = { installDaemon, stopDaemon };
@@ -1,51 +0,0 @@
1
- const MAX_GOOGLE_TTS_CHARS = 200;
2
-
3
- function splitTextForTts(text, maxLength = MAX_GOOGLE_TTS_CHARS) {
4
- const normalized = String(text || '').replace(/\s+/g, ' ').trim();
5
- if (!normalized) return [];
6
-
7
- const chunks = [];
8
- let remaining = normalized;
9
-
10
- while (remaining.length > maxLength) {
11
- const slice = remaining.slice(0, maxLength + 1);
12
- const splitAt = Math.max(
13
- slice.lastIndexOf('.'),
14
- slice.lastIndexOf('?'),
15
- slice.lastIndexOf('!'),
16
- slice.lastIndexOf(','),
17
- slice.lastIndexOf(' ')
18
- );
19
- const safeSplit = splitAt > 0 ? splitAt : maxLength;
20
- chunks.push(remaining.slice(0, safeSplit).trim());
21
- remaining = remaining.slice(safeSplit).trim();
22
- }
23
-
24
- if (remaining) chunks.push(remaining);
25
- return chunks;
26
- }
27
-
28
- function getGoogleTtsUrls(text, options = {}) {
29
- const lang = options.lang || 'en';
30
- const host = options.host || 'https://translate.google.com';
31
- const chunks = splitTextForTts(text);
32
-
33
- return chunks.map((chunk, index) => {
34
- const params = new URLSearchParams({
35
- ie: 'UTF-8',
36
- q: chunk,
37
- tl: lang,
38
- client: 'tw-ob',
39
- idx: String(index),
40
- total: String(chunks.length),
41
- textlen: String(chunk.length)
42
- });
43
-
44
- return {
45
- shortText: chunk,
46
- url: `${host}/translate_tts?${params.toString()}`
47
- };
48
- });
49
- }
50
-
51
- module.exports = { getGoogleTtsUrls, splitTextForTts };
@@ -1,157 +0,0 @@
1
- const { execFile, spawnSync } = require('child_process');
2
- const { screen } = require('electron');
3
-
4
- function commandExists(command) {
5
- const lookup = process.platform === 'win32' ? 'where' : 'which';
6
- const result = spawnSync(lookup, [command], { encoding: 'utf8', shell: false });
7
- return result.status === 0;
8
- }
9
-
10
- function run(command, args = []) {
11
- return new Promise((resolve, reject) => {
12
- execFile(command, args, (err, stdout, stderr) => {
13
- if (err) {
14
- err.stderr = stderr;
15
- reject(err);
16
- return;
17
- }
18
- resolve(stdout);
19
- });
20
- });
21
- }
22
-
23
- function unsupported(feature) {
24
- throw new Error(`${feature} is not supported on ${process.platform} by the current input automation provider.`);
25
- }
26
-
27
- function escapePowerShellSingleQuoted(value) {
28
- return String(value || '').replace(/'/g, "''");
29
- }
30
-
31
- function keyToMacKey(key) {
32
- const value = String(key || '').trim();
33
- const map = {
34
- Enter: 'return',
35
- Return: 'return',
36
- Escape: 'escape',
37
- Esc: 'escape',
38
- Space: 'space',
39
- Backspace: 'delete',
40
- Delete: 'forward delete',
41
- Tab: 'tab'
42
- };
43
- return map[value] || value;
44
- }
45
-
46
- class GranularAutomation {
47
- constructor() {
48
- this.screenWidth = 1920;
49
- this.screenHeight = 1080;
50
- this.updateScreenSize();
51
- }
52
-
53
- updateScreenSize() {
54
- try {
55
- const primaryDisplay = screen.getPrimaryDisplay();
56
- if (primaryDisplay && primaryDisplay.size) {
57
- this.screenWidth = primaryDisplay.size.width;
58
- this.screenHeight = primaryDisplay.size.height;
59
- }
60
- } catch (_) {
61
- // Electron screen can be unavailable in CLI-only contexts.
62
- }
63
- }
64
-
65
- scaleX(x) {
66
- return Math.round((Number(x) / 1000) * this.screenWidth);
67
- }
68
-
69
- scaleY(y) {
70
- return Math.round((Number(y) / 1000) * this.screenHeight);
71
- }
72
-
73
- provider() {
74
- if (process.platform === 'darwin') return macProvider;
75
- if (process.platform === 'win32') return windowsProvider;
76
- return linuxProvider;
77
- }
78
-
79
- mouseMove(x, y) {
80
- return this.provider().mouseMove(this.scaleX(x), this.scaleY(y));
81
- }
82
-
83
- mouseClick(x, y, button = 1) {
84
- return this.provider().mouseClick(this.scaleX(x), this.scaleY(y), button);
85
- }
86
-
87
- typeText(text) {
88
- return this.provider().typeText(String(text || ''));
89
- }
90
-
91
- keyTap(key) {
92
- return this.provider().keyTap(String(key || ''));
93
- }
94
- }
95
-
96
- const linuxProvider = {
97
- mouseMove: (x, y) => run('xdotool', ['mousemove', String(x), String(y)]),
98
- mouseClick: (x, y, button = 1) => run('xdotool', ['mousemove', String(x), String(y), 'click', String(button)]),
99
- typeText: (text) => run('xdotool', ['type', text]),
100
- keyTap: (key) => run('xdotool', ['key', key])
101
- };
102
-
103
- const macProvider = {
104
- mouseMove(x, y) {
105
- if (!commandExists('cliclick')) return unsupported('Mouse move');
106
- return run('cliclick', [`m:${x},${y}`]);
107
- },
108
- mouseClick(x, y) {
109
- if (!commandExists('cliclick')) return unsupported('Mouse click');
110
- return run('cliclick', [`c:${x},${y}`]);
111
- },
112
- typeText(text) {
113
- if (commandExists('cliclick')) return run('cliclick', [`t:${text}`]);
114
- return run('osascript', ['-e', `tell application "System Events" to keystroke ${JSON.stringify(text)}`]);
115
- },
116
- keyTap(key) {
117
- const macKey = keyToMacKey(key);
118
- if (commandExists('cliclick')) return run('cliclick', [`kp:${macKey}`]);
119
- if (macKey.length === 1) {
120
- return run('osascript', ['-e', `tell application "System Events" to keystroke ${JSON.stringify(macKey)}`]);
121
- }
122
- return unsupported('Special key tap without cliclick');
123
- }
124
- };
125
-
126
- const windowsProvider = {
127
- mouseMove(x, y) {
128
- const script = `[void][Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms'); [System.Windows.Forms.Cursor]::Position = New-Object System.Drawing.Point(${x}, ${y})`;
129
- return run('powershell.exe', ['-NoProfile', '-NonInteractive', '-Command', script]);
130
- },
131
- mouseClick(x, y, button = 1) {
132
- const down = Number(button) === 2 ? '0x0008' : '0x0002';
133
- const up = Number(button) === 2 ? '0x0010' : '0x0004';
134
- const script = [
135
- "Add-Type -MemberDefinition '[DllImport(\"user32.dll\")] public static extern bool SetCursorPos(int X,int Y); [DllImport(\"user32.dll\")] public static extern void mouse_event(int dwFlags,int dx,int dy,int dwData,int dwExtraInfo);' -Name NativeMouse -Namespace Mint;",
136
- `[Mint.NativeMouse]::SetCursorPos(${x}, ${y}) | Out-Null;`,
137
- `[Mint.NativeMouse]::mouse_event(${down},0,0,0,0);`,
138
- `[Mint.NativeMouse]::mouse_event(${up},0,0,0,0);`
139
- ].join(' ');
140
- return run('powershell.exe', ['-NoProfile', '-NonInteractive', '-Command', script]);
141
- },
142
- typeText(text) {
143
- const safe = escapePowerShellSingleQuoted(text);
144
- const script = `Add-Type -AssemblyName System.Windows.Forms; [System.Windows.Forms.SendKeys]::SendWait('${safe}')`;
145
- return run('powershell.exe', ['-NoProfile', '-NonInteractive', '-Command', script]);
146
- },
147
- keyTap(key) {
148
- const safe = escapePowerShellSingleQuoted(key);
149
- const script = `Add-Type -AssemblyName System.Windows.Forms; [System.Windows.Forms.SendKeys]::SendWait('{${safe}}')`;
150
- return run('powershell.exe', ['-NoProfile', '-NonInteractive', '-Command', script]);
151
- }
152
- };
153
-
154
- const instance = new GranularAutomation();
155
- instance._providers = { linuxProvider, macProvider, windowsProvider, commandExists };
156
-
157
- module.exports = instance;