@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.
- package/.codex +0 -0
- package/.github/FUNDING.yml +2 -0
- package/.github/workflows/ci.yml +45 -0
- package/.github/workflows/release.yml +79 -0
- package/Cargo.lock +5792 -0
- package/Cargo.toml +32 -0
- package/README.md +387 -353
- package/assets/icon.png +0 -0
- package/bin/mint +0 -0
- package/crates/mint-cli/Cargo.toml +23 -0
- package/crates/mint-cli/src/agent.rs +851 -0
- package/crates/mint-cli/src/gmail.rs +216 -0
- package/crates/mint-cli/src/image.rs +142 -0
- package/crates/mint-cli/src/main.rs +2837 -0
- package/crates/mint-cli/src/mcp.rs +63 -0
- package/crates/mint-cli/src/onboard.rs +1149 -0
- package/crates/mint-cli/src/setup.rs +390 -0
- package/crates/mint-cli/src/skills.rs +8 -0
- package/crates/mint-cli/src/updater.rs +279 -0
- package/crates/mint-core/Cargo.toml +22 -0
- package/crates/mint-core/src/agent_loop.rs +94 -0
- package/crates/mint-core/src/api_server.rs +991 -0
- package/crates/mint-core/src/channels.rs +248 -0
- package/crates/mint-core/src/chat.rs +895 -0
- package/crates/mint-core/src/code_tools.rs +729 -0
- package/crates/mint-core/src/config.rs +368 -0
- package/crates/mint-core/src/files.rs +159 -0
- package/crates/mint-core/src/knowledge.rs +541 -0
- package/crates/mint-core/src/lib.rs +84 -0
- package/crates/mint-core/src/mcp.rs +273 -0
- package/crates/mint-core/src/memory.rs +673 -0
- package/crates/mint-core/src/orchestration.rs +2157 -0
- package/crates/mint-core/src/pictures.rs +314 -0
- package/crates/mint-core/src/plugins.rs +727 -0
- package/crates/mint-core/src/safety.rs +416 -0
- package/crates/mint-core/src/semantic.rs +254 -0
- package/crates/mint-core/src/shell.rs +317 -0
- package/crates/mint-core/src/skills.rs +71 -0
- package/crates/mint-core/src/symbols.rs +157 -0
- package/crates/mint-core/src/tasks.rs +308 -0
- package/crates/mint-core/src/tts.rs +92 -0
- package/crates/mint-core/src/weather.rs +93 -0
- package/crates/mint-core/src/web_search.rs +200 -0
- package/crates/mint-core/src/workflows.rs +81 -0
- package/crates/mint-core/tests/mcp_stdio.rs +45 -0
- package/crates/mint-core/tests/memory_persistence.rs +172 -0
- package/crates/mint-core/tests/pictures_storage.rs +14 -0
- package/crates/mint-core/tests/task_lifecycle.rs +87 -0
- package/package.json +35 -99
- package/src/bin/index.js +16 -0
- package/src/renderer/index-web.html +17 -0
- package/src/renderer/index.html +17 -0
- package/src/renderer/public/Live2DCubismCore.js +9 -0
- package/src/renderer/public/assets/icon.png +0 -0
- package/src/renderer/public/models/Shiroko_Model/Shiroko/Shiroko_Core/shiroko.model3.json +36 -0
- package/src/renderer/src/App.tsx +33 -0
- package/src/renderer/src/calculator.ts +47 -0
- package/src/renderer/src/components/ChatPanel.tsx +1598 -0
- package/src/renderer/src/components/DashboardSidebar.tsx +358 -0
- package/src/renderer/src/components/Live2DStage.tsx +374 -0
- package/src/renderer/src/components/MintDashboard.tsx +950 -0
- package/src/renderer/src/components/ModelPanel.tsx +154 -0
- package/src/renderer/src/components/PicturesLibrary.tsx +46 -0
- package/src/renderer/src/components/ProactiveGlow.tsx +19 -0
- package/src/renderer/src/components/ScreenPicker.tsx +579 -0
- package/src/renderer/src/components/SettingsWindow.tsx +1467 -0
- package/src/renderer/src/components/SpotlightWindow.tsx +280 -0
- package/src/renderer/src/components/WidgetWindow.tsx +36 -0
- package/src/renderer/src/components/WorkspacePanel.tsx +268 -0
- package/src/{UI → renderer/src/css}/settings.css +69 -16
- package/src/renderer/src/css/spotlight.css +113 -0
- package/src/renderer/src/css/styles.css +3722 -0
- package/src/renderer/src/css/widget.css +185 -0
- package/src/renderer/src/env.d.ts +116 -0
- package/src/renderer/src/index.css +379 -0
- package/src/renderer/src/main.tsx +13 -0
- package/src/renderer/src/tauri.ts +996 -0
- package/src/renderer/src-web/App.tsx +25 -0
- package/src/renderer/src-web/calculator.ts +47 -0
- package/src/renderer/src-web/components/ChatPanel.tsx +1662 -0
- package/src/renderer/src-web/components/DashboardSidebar.tsx +242 -0
- package/src/renderer/src-web/components/MintDashboard.tsx +763 -0
- package/src/renderer/src-web/components/PicturesLibrary.tsx +73 -0
- package/src/renderer/src-web/components/SettingsWindow.tsx +1500 -0
- package/src/renderer/src-web/css/settings.css +1100 -0
- package/src/{UI → renderer/src-web/css}/spotlight.css +4 -4
- package/src/{UI → renderer/src-web/css}/styles.css +1055 -159
- package/src/{UI → renderer/src-web/css}/widget.css +2 -2
- package/src/renderer/src-web/env.d.ts +107 -0
- package/src/renderer/src-web/index.css +379 -0
- package/src/renderer/src-web/main.tsx +13 -0
- package/src/renderer/src-web/tauri.ts +983 -0
- package/tsconfig.json +30 -0
- package/vite.config.ts +33 -0
- package/vite.config.web.ts +51 -0
- package/GUIDE_TH.md +0 -125
- package/assets/Agent_Mint.png +0 -0
- package/assets/CLI_Screen.png +0 -0
- package/assets/Settings.png +0 -0
- package/benchmark_ai.js +0 -71
- package/install.ps1 +0 -64
- package/install.sh +0 -54
- package/main.js +0 -139
- package/mint-cli-logic.js +0 -3
- package/mint-cli.js +0 -410
- package/models/Shiroko_Model/Shiroko/Shiroko_Core//351/235/242/351/245/2740.model3.json +0 -47
- 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
- package/preload-picker.js +0 -11
- package/preload-settings.js +0 -11
- package/preload.js +0 -41
- package/scripts/install_linux_desktop_entry.js +0 -48
- package/src/AI_Brain/Gemini_API.js +0 -813
- package/src/AI_Brain/agent_orchestrator.js +0 -73
- package/src/AI_Brain/autonomous_brain.js +0 -179
- package/src/AI_Brain/behavior_memory.js +0 -135
- package/src/AI_Brain/headless_agent.js +0 -143
- package/src/AI_Brain/knowledge_base.js +0 -349
- package/src/AI_Brain/memory_store.js +0 -662
- package/src/AI_Brain/proactive_engine.js +0 -172
- package/src/AI_Brain/provider_adapter.js +0 -365
- package/src/Automation_Layer/browser_automation.js +0 -149
- package/src/Automation_Layer/file_operations.js +0 -286
- package/src/Automation_Layer/open_app.js +0 -85
- package/src/Automation_Layer/open_website.js +0 -38
- package/src/CLI/approval_handler.js +0 -47
- package/src/CLI/chat_router.js +0 -247
- package/src/CLI/chat_ui.js +0 -1159
- package/src/CLI/cli_colors.js +0 -115
- package/src/CLI/cli_formatters.js +0 -94
- package/src/CLI/code_agent.js +0 -1667
- package/src/CLI/code_session_memory.js +0 -62
- package/src/CLI/gmail_auth.js +0 -210
- package/src/CLI/image_input.js +0 -90
- package/src/CLI/intent_detectors.js +0 -181
- package/src/CLI/interactive_chat.js +0 -658
- package/src/CLI/list_features.js +0 -64
- package/src/CLI/onboarding.js +0 -416
- package/src/CLI/repo_summarizer.js +0 -282
- package/src/CLI/semantic_code_search.js +0 -312
- package/src/CLI/skill_manager.js +0 -41
- package/src/CLI/slash_command_handler.js +0 -418
- package/src/CLI/symbol_indexer.js +0 -231
- package/src/CLI/updater.js +0 -230
- package/src/CLI/workspace_manager.js +0 -90
- package/src/Channels/brave_search_bridge.js +0 -35
- package/src/Channels/discord_bridge.js +0 -66
- package/src/Channels/google_search_bridge.js +0 -38
- package/src/Channels/line_bridge.js +0 -60
- package/src/Channels/slack_bridge.js +0 -48
- package/src/Channels/telegram_bridge.js +0 -41
- package/src/Channels/whatsapp_bridge.js +0 -57
- package/src/Command_Parser/parser.js +0 -45
- package/src/Plugins/dev_tools.js +0 -41
- package/src/Plugins/discord.js +0 -20
- package/src/Plugins/docker.js +0 -47
- package/src/Plugins/gmail.js +0 -251
- package/src/Plugins/google_calendar.js +0 -252
- package/src/Plugins/mcp_manager.js +0 -95
- package/src/Plugins/notion.js +0 -256
- package/src/Plugins/obsidian.js +0 -54
- package/src/Plugins/plugin_manager.js +0 -81
- package/src/Plugins/spotify.js +0 -173
- package/src/Plugins/system_metrics.js +0 -31
- package/src/Plugins/system_monitor.js +0 -72
- package/src/System/action_executor.js +0 -178
- package/src/System/bridge_manager.js +0 -76
- package/src/System/chat_history_manager.js +0 -83
- package/src/System/config_manager.js +0 -194
- package/src/System/custom_workflows.js +0 -163
- package/src/System/daemon_manager.js +0 -67
- package/src/System/google_tts_urls.js +0 -51
- package/src/System/granular_automation.js +0 -157
- package/src/System/ipc_handlers.js +0 -332
- package/src/System/notifications.js +0 -23
- package/src/System/optional_require.js +0 -23
- package/src/System/picture_store.js +0 -109
- package/src/System/proactive_loop.js +0 -153
- package/src/System/safety_manager.js +0 -273
- package/src/System/sandbox_runner.js +0 -182
- package/src/System/screen_capture.js +0 -175
- package/src/System/smart_context.js +0 -227
- package/src/System/system_automation.js +0 -162
- package/src/System/system_events.js +0 -79
- package/src/System/system_info.js +0 -125
- package/src/System/task_manager.js +0 -222
- package/src/System/tool_registry.js +0 -293
- package/src/System/window_manager.js +0 -220
- package/src/UI/floating.css +0 -80
- package/src/UI/floating.html +0 -17
- package/src/UI/floating.js +0 -67
- package/src/UI/live2d_manager.js +0 -600
- package/src/UI/preload-floating.js +0 -7
- package/src/UI/preload-spotlight.js +0 -11
- package/src/UI/preload-widget.js +0 -5
- package/src/UI/proactive-glow.html +0 -42
- package/src/UI/renderer.js +0 -2127
- package/src/UI/screenPicker.html +0 -214
- package/src/UI/screenPicker.js +0 -262
- package/src/UI/settings.html +0 -577
- package/src/UI/settings.js +0 -770
- package/src/UI/spotlight.html +0 -23
- package/src/UI/spotlight.js +0 -185
- package/src/UI/widget.html +0 -29
- package/src/UI/widget.js +0 -10
- /package/{models → src/renderer/public/models}/Shiroko_Model/Shiroko/Shiroko_Core/72d86db84cfa9730b894c241fd24c0db.png +0 -0
- /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
- /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
- /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
- /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
- /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
- /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
- /package/{models → src/renderer/public/models}/Shiroko_Model/Shiroko/Shiroko_Core/items_pinned_to_model.json +0 -0
- /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
- /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
- /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
- /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
- /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
- /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
- /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
- /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
- /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
- /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;
|