@pheem49/mint 1.4.2 → 1.5.0
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/GUIDE_TH.md +113 -0
- package/README.md +239 -76
- package/assets/CLI_Screen.png +0 -0
- package/docs/assets/CLI_Screen.png +0 -0
- package/docs/guide.html +632 -0
- package/docs/index.html +5 -4
- package/main.js +66 -894
- package/mint-cli-logic.js +13 -1
- package/mint-cli.js +100 -9
- package/package.json +12 -4
- package/src/AI_Brain/Gemini_API.js +77 -20
- package/src/AI_Brain/autonomous_brain.js +10 -0
- package/src/AI_Brain/behavior_memory.js +26 -5
- package/src/AI_Brain/headless_agent.js +4 -0
- package/src/AI_Brain/knowledge_base.js +61 -8
- package/src/AI_Brain/memory_store.js +55 -7
- package/src/Automation_Layer/file_operations.js +1 -1
- package/src/CLI/chat_router.js +3 -2
- package/src/CLI/chat_ui.js +263 -838
- package/src/CLI/code_agent.js +144 -42
- package/src/CLI/gmail_auth.js +210 -0
- package/src/CLI/list_features.js +2 -0
- package/src/CLI/onboarding.js +307 -55
- package/src/CLI/updater.js +208 -0
- package/src/Channels/brave_search_bridge.js +35 -0
- package/src/Channels/discord_bridge.js +68 -0
- package/src/Channels/google_search_bridge.js +38 -0
- package/src/Channels/line_bridge.js +60 -0
- package/src/Channels/slack_bridge.js +53 -0
- package/src/Channels/telegram_bridge.js +49 -0
- package/src/Channels/whatsapp_bridge.js +55 -0
- package/src/Command_Parser/parser.js +12 -1
- package/src/Plugins/gmail.js +251 -0
- package/src/Plugins/google_calendar.js +245 -19
- package/src/Plugins/notion.js +256 -0
- package/src/System/action_executor.js +129 -0
- package/src/System/bridge_manager.js +76 -0
- package/src/System/chat_history_manager.js +23 -5
- package/src/System/config_manager.js +41 -7
- package/src/System/custom_workflows.js +31 -2
- package/src/System/google_tts_urls.js +51 -0
- package/src/System/ipc_handlers.js +238 -0
- package/src/System/proactive_loop.js +137 -0
- package/src/System/safety_manager.js +165 -0
- package/src/System/screen_capture.js +175 -0
- package/src/System/task_manager.js +15 -5
- package/src/System/window_manager.js +210 -0
- package/src/UI/renderer.js +33 -7
- package/src/UI/settings.html +24 -0
- package/src/UI/settings.js +14 -4
- package/src/UI/styles.css +14 -1
- package/tests/action_executor_safety.test.js +67 -0
- package/tests/gmail.test.js +135 -0
- package/tests/gmail_auth.test.js +129 -0
- package/tests/google_calendar.test.js +113 -0
- package/tests/google_tts_urls.test.js +24 -0
- package/tests/notion.test.js +121 -0
- package/tests/provider_routing.test.js +17 -1
- package/tests/safety_manager.test.js +40 -0
- package/tests/updater.test.js +32 -0
|
@@ -25,12 +25,32 @@ try {
|
|
|
25
25
|
|
|
26
26
|
function getDbPath() {
|
|
27
27
|
const fileName = 'mint-knowledge.sqlite'; // shared DB with knowledge_base
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
const configDir = path.join(os.homedir(), '.config', 'mint');
|
|
29
|
+
const dbPath = path.join(configDir, fileName);
|
|
30
|
+
|
|
31
|
+
if (!fs.existsSync(configDir)) {
|
|
32
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
30
33
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
+
|
|
35
|
+
// Migration Logic
|
|
36
|
+
if (!fs.existsSync(dbPath)) {
|
|
37
|
+
const electronDb = app && app.getPath ? path.join(app.getPath('userData'), fileName) : null;
|
|
38
|
+
const legacyDb = path.join(os.homedir(), '.mint', fileName);
|
|
39
|
+
|
|
40
|
+
if (electronDb && fs.existsSync(electronDb)) {
|
|
41
|
+
try {
|
|
42
|
+
fs.copyFileSync(electronDb, dbPath);
|
|
43
|
+
console.log('[Memory] Migrated database from Electron userData');
|
|
44
|
+
} catch (e) { console.error('[Memory] Migration from Electron failed:', e); }
|
|
45
|
+
} else if (fs.existsSync(legacyDb)) {
|
|
46
|
+
try {
|
|
47
|
+
fs.copyFileSync(legacyDb, dbPath);
|
|
48
|
+
console.log('[Memory] Migrated database from ~/.mint');
|
|
49
|
+
} catch (e) { console.error('[Memory] Migration from ~/.mint failed:', e); }
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return dbPath;
|
|
34
54
|
}
|
|
35
55
|
|
|
36
56
|
// ── Lazy DatabaseSync init ─────────────────────────────────────────────────
|
|
@@ -45,6 +65,10 @@ function getDb() {
|
|
|
45
65
|
if (dbInstance) return dbInstance;
|
|
46
66
|
const Database = getDatabaseSync();
|
|
47
67
|
dbInstance = new Database(getDbPath());
|
|
68
|
+
|
|
69
|
+
// Enable WAL mode for better concurrency
|
|
70
|
+
dbInstance.exec('PRAGMA journal_mode = WAL;');
|
|
71
|
+
dbInstance.exec('PRAGMA synchronous = NORMAL;');
|
|
48
72
|
|
|
49
73
|
dbInstance.exec(`
|
|
50
74
|
-- User profile: arbitrary key-value pairs
|
|
@@ -94,6 +118,19 @@ function setProfile(key, value) {
|
|
|
94
118
|
}
|
|
95
119
|
}
|
|
96
120
|
|
|
121
|
+
function deleteProfile(key) {
|
|
122
|
+
try {
|
|
123
|
+
getDb().prepare('DELETE FROM user_profile WHERE key = ?').run(key);
|
|
124
|
+
} catch (err) {
|
|
125
|
+
console.error('[Memory] deleteProfile error:', err.message);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function clearConversationScopedProfile() {
|
|
130
|
+
deleteProfile('preferred_language');
|
|
131
|
+
clearResponseCache();
|
|
132
|
+
}
|
|
133
|
+
|
|
97
134
|
function getProfile(key, defaultValue = null) {
|
|
98
135
|
try {
|
|
99
136
|
const row = getDb().prepare('SELECT value FROM user_profile WHERE key = ?').get(key);
|
|
@@ -246,7 +283,7 @@ function getUserContext() {
|
|
|
246
283
|
// Profile info
|
|
247
284
|
if (Object.keys(profile).length > 0) {
|
|
248
285
|
if (profile.preferred_language)
|
|
249
|
-
lines.push(`•
|
|
286
|
+
lines.push(`• Previously inferred language: ${profile.preferred_language} (do not override the current user message language)`);
|
|
250
287
|
if (profile.last_active_project)
|
|
251
288
|
lines.push(`• Last active project: ${profile.last_active_project} (${profile.last_active_project_path || ''})`);
|
|
252
289
|
if (profile.total_interactions)
|
|
@@ -305,14 +342,25 @@ function cacheResponse(query, responseObj) {
|
|
|
305
342
|
} catch (_) {}
|
|
306
343
|
}
|
|
307
344
|
|
|
345
|
+
function clearResponseCache() {
|
|
346
|
+
try {
|
|
347
|
+
getDb().prepare('DELETE FROM response_cache').run();
|
|
348
|
+
} catch (err) {
|
|
349
|
+
console.error('[Memory] clearResponseCache error:', err.message);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
308
353
|
module.exports = {
|
|
309
354
|
recordInteraction,
|
|
310
355
|
saveSessionSummary,
|
|
311
356
|
getUserContext,
|
|
312
357
|
setProfile,
|
|
358
|
+
deleteProfile,
|
|
359
|
+
clearConversationScopedProfile,
|
|
313
360
|
getProfile,
|
|
314
361
|
getTopPatterns,
|
|
315
362
|
getRecentMemories,
|
|
316
363
|
getCachedResponse,
|
|
317
|
-
cacheResponse
|
|
364
|
+
cacheResponse,
|
|
365
|
+
clearResponseCache
|
|
318
366
|
};
|
|
@@ -226,7 +226,7 @@ async function openFile(target) {
|
|
|
226
226
|
// ใช้ exec เพื่อให้รันผ่าน shell และรองรับการทำ fallback
|
|
227
227
|
let cmd = `${platformCmd} "${resolvedPath}"`;
|
|
228
228
|
if (process.platform === 'linux') {
|
|
229
|
-
cmd = `xdg-open "${resolvedPath}" || gio open "${resolvedPath}" || nautilus "${resolvedPath}"`;
|
|
229
|
+
cmd = `xdg-open "${resolvedPath}" || gio open "${resolvedPath}" || nautilus "${resolvedPath}" || nemo "${resolvedPath}" || thunar "${resolvedPath}" || dolphin "${resolvedPath}"`;
|
|
230
230
|
}
|
|
231
231
|
|
|
232
232
|
exec(cmd, (err) => {
|
package/src/CLI/chat_router.js
CHANGED
|
@@ -170,7 +170,7 @@ async function detectCodeIntent(text, workspaceRoot = process.cwd(), history = [
|
|
|
170
170
|
|
|
171
171
|
async function runChatRoutedTask(input, context) {
|
|
172
172
|
const text = input.startsWith('/code ') ? input.slice('/code '.length).trim() : input;
|
|
173
|
-
const { appendMessage, setThinking, requestApproval, setMode, history } = context;
|
|
173
|
+
const { appendMessage, setThinking, requestApproval, askUser, setMode, history } = context;
|
|
174
174
|
|
|
175
175
|
const config = readConfig();
|
|
176
176
|
const availableProviders = getAvailableProviders(config);
|
|
@@ -190,6 +190,7 @@ async function runChatRoutedTask(input, context) {
|
|
|
190
190
|
const result = await executeCodeTask(text, {
|
|
191
191
|
cwd: process.cwd(),
|
|
192
192
|
requestApproval,
|
|
193
|
+
askUser,
|
|
193
194
|
provider: preferredProvider,
|
|
194
195
|
history: history,
|
|
195
196
|
onProgress: (info) => {
|
|
@@ -206,7 +207,7 @@ async function runChatRoutedTask(input, context) {
|
|
|
206
207
|
`Code Mode finished.`,
|
|
207
208
|
result.summary,
|
|
208
209
|
`Verification: ${result.verification}`
|
|
209
|
-
].join('\n'));
|
|
210
|
+
].join('\n'), { providerInfo: result.providerInfo });
|
|
210
211
|
} catch (error) {
|
|
211
212
|
clearInterval(timer);
|
|
212
213
|
setThinking(false);
|