@pheem49/mint 1.8.0 → 1.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (200) hide show
  1. package/.github/workflows/release.yml +1 -1
  2. package/Cargo.lock +34 -3
  3. package/Cargo.toml +2 -2
  4. package/README.md +20 -6
  5. package/Release_Note.md +129 -0
  6. package/assets/Mint_CLI.png +0 -0
  7. package/bin/mint +0 -0
  8. package/crates/mint-cli/Cargo.toml +1 -0
  9. package/crates/mint-cli/src/agent.rs +242 -54
  10. package/crates/mint-cli/src/main.rs +397 -74
  11. package/crates/mint-core/src/agent_loop.rs +1 -0
  12. package/crates/mint-core/src/api_server.rs +64 -2
  13. package/crates/mint-core/src/browser.rs +456 -0
  14. package/crates/mint-core/src/channels.rs +1 -0
  15. package/crates/mint-core/src/chat.rs +3 -0
  16. package/crates/mint-core/src/config.rs +130 -1
  17. package/crates/mint-core/src/lib.rs +19 -0
  18. package/crates/mint-core/src/orchestration.rs +317 -12
  19. package/crates/mint-core/src/skills.rs +113 -4
  20. package/crates/mint-core/src/tts.rs +3 -1
  21. package/crates/mint-core/src/workflows.rs +1 -22
  22. package/flatpak/com.pheem49.mint.desktop +9 -0
  23. package/flatpak/com.pheem49.mint.metainfo.xml +35 -0
  24. package/flatpak/com.pheem49.mint.yaml +52 -0
  25. package/package.json +1 -1
  26. package/shared-modules/.github/workflows/ci.yml +120 -0
  27. package/shared-modules/.github/workflows/update.yaml +28 -0
  28. package/shared-modules/CODEOWNERS +23 -0
  29. package/shared-modules/README.md +79 -0
  30. package/shared-modules/SDL/README.md +3 -0
  31. package/shared-modules/SDL/SDL-1.2.15.json +51 -0
  32. package/shared-modules/SDL/SDL_Pango-0.1.2-API-adds.patch +118 -0
  33. package/shared-modules/SDL/SDL_image-1.2.12.json +25 -0
  34. package/shared-modules/SDL/SDL_mixer-1.2.12.json +27 -0
  35. package/shared-modules/SDL/SDL_net-1.2.8.json +19 -0
  36. package/shared-modules/SDL/SDL_pango-0.1.2.json +26 -0
  37. package/shared-modules/SDL/SDL_ttf-2.0.11.json +28 -0
  38. package/shared-modules/SDL/libsdl-1.2.15-strict-prototypes.patch +316 -0
  39. package/shared-modules/SDL/sdl-check-for-SDL_VIDEO_X11_BACKINGSTORE.patch +24 -0
  40. package/shared-modules/SDL/sdl-libx11-build.patch +59 -0
  41. package/shared-modules/SDL/sdl-sysloadso-buffer-length.patch +27 -0
  42. package/shared-modules/SDL/sdl12-compat.json +22 -0
  43. package/shared-modules/SDL2/SDL2_image.json +27 -0
  44. package/shared-modules/SDL2/SDL2_ttf.json +29 -0
  45. package/shared-modules/cld2/CMakeLists.txt +157 -0
  46. package/shared-modules/cld2/cld2.json +24 -0
  47. package/shared-modules/clutter/clutter.json +72 -0
  48. package/shared-modules/dbus-glib/dbus-glib.json +29 -0
  49. package/shared-modules/glew/glew.json +36 -0
  50. package/shared-modules/glu/glu-9.json +12 -0
  51. package/shared-modules/gtk2/arc-gtk2-theme-Replace-Inkscape-dependency-with-rsvg-convert.patch +180 -0
  52. package/shared-modules/gtk2/gtk2-common-themes.json +360 -0
  53. package/shared-modules/gtk2/gtk2-fix-crash-in-show-uri.patch +30 -0
  54. package/shared-modules/gtk2/gtk2-gcc14.patch +281 -0
  55. package/shared-modules/gtk2/gtk2-gcc15.patch +250 -0
  56. package/shared-modules/gtk2/gtk2-murrine-c99.patch +34 -0
  57. package/shared-modules/gtk2/gtk2-use-adwaita-theme.patch +80 -0
  58. package/shared-modules/gtk2/gtk2.json +120 -0
  59. package/shared-modules/gtk2/ibus-gcc15.patch +13 -0
  60. package/shared-modules/gtk2/murrine-engine-fix-crash.patch +12 -0
  61. package/shared-modules/gtk2/readme.md +10 -0
  62. package/shared-modules/intltool/intltool-0.51.json +20 -0
  63. package/shared-modules/intltool/intltool-perl5.26-regex-fixes.patch +59 -0
  64. package/shared-modules/lame/0001-Build-xmm_quantize_sub.c-with-msse.patch +34 -0
  65. package/shared-modules/lame/0002-Include-GTK-1-autoconf-directives-in-build-system.patch +222 -0
  66. package/shared-modules/lame/0003-Patch-out-remaining-ansi2knr.patch +70 -0
  67. package/shared-modules/lame/0004-initscr-is-not-used-anywhere-in-lame-sourcetree.patch +41 -0
  68. package/shared-modules/lame/0005-Update-autoconf.patch +81 -0
  69. package/shared-modules/lame/lame-3.99.5.json +32 -0
  70. package/shared-modules/libappindicator/libappindicator-gtk2-12.10.json +140 -0
  71. package/shared-modules/libappindicator/libappindicator-gtk3-12.10.json +140 -0
  72. package/shared-modules/libappindicator/libappindicator-gtk3-introspection-12.10.json +140 -0
  73. package/shared-modules/libappindicator/patches/0001-libappindicator-ftbfs.patch +20 -0
  74. package/shared-modules/libappindicator/patches/0002-libappindicator-no-python.patch +888 -0
  75. package/shared-modules/libappindicator/patches/0003-libappindicator-fix-crash-from-incorrect-signal-emission.patch +74 -0
  76. package/shared-modules/libappindicator/patches/0004-libappindicator-fix-crash-iterating-icon-themes.patch +11 -0
  77. package/shared-modules/libayatana-appindicator/0001-Fix-HAVE_VALGRIND-AM_CONDITIONAL.patch +51 -0
  78. package/shared-modules/libayatana-appindicator/0001-Make-introspection-configurable.patch +44 -0
  79. package/shared-modules/libayatana-appindicator/libayatana-appindicator-gtk3.json +121 -0
  80. package/shared-modules/libcanberra/0001-gtk-Don-t-assume-all-GdkDisplays-are-GdkX11Displays-.patch +123 -0
  81. package/shared-modules/libcanberra/libcanberra.json +44 -0
  82. package/shared-modules/libmad/libmad.json +19 -0
  83. package/shared-modules/libsecret/libsecret.json +23 -0
  84. package/shared-modules/libsoup/libsoup-2.4.json +14 -0
  85. package/shared-modules/libusb/libusb.json +27 -0
  86. package/shared-modules/linux-audio/dssi.json +31 -0
  87. package/shared-modules/linux-audio/fftw3f-static.json +44 -0
  88. package/shared-modules/linux-audio/fftw3f.json +42 -0
  89. package/shared-modules/linux-audio/fluidsynth2-static.json +30 -0
  90. package/shared-modules/linux-audio/fluidsynth2.json +19 -0
  91. package/shared-modules/linux-audio/ladspa.json +26 -0
  92. package/shared-modules/linux-audio/lash.json +35 -0
  93. package/shared-modules/linux-audio/libinstpatch.json +16 -0
  94. package/shared-modules/linux-audio/liblo-static.json +22 -0
  95. package/shared-modules/linux-audio/liblo.json +17 -0
  96. package/shared-modules/linux-audio/lilv-static.json +94 -0
  97. package/shared-modules/linux-audio/lilv.json +82 -0
  98. package/shared-modules/linux-audio/lrdf.json +57 -0
  99. package/shared-modules/linux-audio/lv2.json +21 -0
  100. package/shared-modules/linux-audio/patches/lash/0001-configure-remove-aclocal-m4.patch +29 -0
  101. package/shared-modules/linux-audio/patches/lash/0002-Fix-build-with-recent-gcc.patch +73 -0
  102. package/shared-modules/linux-audio/patches/lash/0003-Fix-linking.patch +136 -0
  103. package/shared-modules/linux-audio/patches/raptor-libxml.patch +31 -0
  104. package/shared-modules/linux-audio/patches/stk-install.sh +54 -0
  105. package/shared-modules/linux-audio/stk.json +28 -0
  106. package/shared-modules/lua5.1/0004-Fix-stack-overflow-in-vararg-functions.patch +21 -0
  107. package/shared-modules/lua5.1/lua-5.1.5-so.patch +43 -0
  108. package/shared-modules/lua5.1/lua-5.1.5.json +42 -0
  109. package/shared-modules/lua5.3/lua-5.3.5.json +41 -0
  110. package/shared-modules/lua5.3/lua.pc.in +8 -0
  111. package/shared-modules/lua5.3/luaconf.patch +47 -0
  112. package/shared-modules/lua5.3/makefile-add-liblua.so-rule.patch +47 -0
  113. package/shared-modules/lua5.4/lua-5.4.json +41 -0
  114. package/shared-modules/lua5.4/lua.pc.in +8 -0
  115. package/shared-modules/lua5.4/luaconf.patch +34 -0
  116. package/shared-modules/lua5.4/makefile-add-liblua.so-rule.patch +42 -0
  117. package/shared-modules/luajit/luajit.json +30 -0
  118. package/shared-modules/lzo/lzo.json +27 -0
  119. package/shared-modules/mac/mac.json +18 -0
  120. package/shared-modules/physfs/physfs.json +26 -0
  121. package/shared-modules/pygame/audiofile-gcc6.patch +21 -0
  122. package/shared-modules/pygame/cython-fixes.patch +34 -0
  123. package/shared-modules/pygame/fluidsynth-no-rawmidi.patch +69 -0
  124. package/shared-modules/pygame/glib.patch +25 -0
  125. package/shared-modules/pygame/pygame1-python2.json +157 -0
  126. package/shared-modules/pygtk/pygtk-c99.patch +15 -0
  127. package/shared-modules/pygtk/pygtk.json +117 -0
  128. package/shared-modules/pygtk/pygtk.patch +39 -0
  129. package/shared-modules/python2.7/python-2.7.json +48 -0
  130. package/shared-modules/smpeg/smpeg-0.4.5.json +50 -0
  131. package/shared-modules/smpeg/smpeg-am-prog-as.patch +12 -0
  132. package/shared-modules/smpeg/smpeg-export-mpegaudio-class.patch +17 -0
  133. package/shared-modules/smpeg/smpeg-gcc6.patch +40 -0
  134. package/shared-modules/smpeg/smpeg-no-gtk.patch +37 -0
  135. package/shared-modules/squashfs-tools/squashfs-tools.json +25 -0
  136. package/shared-modules/update-checker.sh +50 -0
  137. package/shared-modules/vorbisgain/0001-temp_files.patch +75 -0
  138. package/shared-modules/vorbisgain/0002-errno.patch +33 -0
  139. package/shared-modules/vorbisgain/0003-manpage.patch +248 -0
  140. package/shared-modules/vorbisgain/0004-vorbisgain_mtime.patch +183 -0
  141. package/shared-modules/vorbisgain/0005-double_fclose.patch +21 -0
  142. package/shared-modules/vorbisgain/0006-manpage_hyphens.patch +56 -0
  143. package/shared-modules/vorbisgain/0007-recursively_spelling.patch +14 -0
  144. package/shared-modules/vorbisgain/0008-manpage_recursion_mistake.patch +23 -0
  145. package/shared-modules/vorbisgain/0009-hardening.patch +13 -0
  146. package/shared-modules/vorbisgain/0010-fclose.patch +13 -0
  147. package/shared-modules/vorbisgain/README.md +23 -0
  148. package/shared-modules/vorbisgain/vorbisgain_0.37-2.json +29 -0
  149. package/src/renderer/shared/agentProgress.ts +145 -0
  150. package/src/renderer/shared/calculator.ts +52 -0
  151. package/src/renderer/shared/components/AgentActivityDrawer.tsx +72 -0
  152. package/src/renderer/shared/components/AgentActivityTable.tsx +66 -0
  153. package/src/renderer/shared/components/ApprovalCard.tsx +93 -0
  154. package/src/renderer/shared/components/ChatCodeBlock.tsx +75 -0
  155. package/src/renderer/shared/components/ThinkingBlock.tsx +101 -0
  156. package/src/renderer/shared/constants/models.ts +91 -0
  157. package/src/renderer/shared/platform.ts +82 -0
  158. package/src/renderer/shared/types.ts +140 -0
  159. package/src/renderer/shared/utils/agentActivity.ts +187 -0
  160. package/src/renderer/shared/utils/approval.ts +1 -0
  161. package/src/renderer/shared/utils/approval.tsx +64 -0
  162. package/src/renderer/shared/utils/markdown.tsx +347 -0
  163. package/src/renderer/shared/utils/providers.ts +36 -0
  164. package/src/renderer/shared/utils/speech.ts +216 -0
  165. package/src/renderer/shared/utils/ui.ts +147 -0
  166. package/src/renderer/src/agentProgress.ts +11 -39
  167. package/src/renderer/src/calculator.ts +3 -46
  168. package/src/renderer/src/components/ChatPanel.tsx +230 -1202
  169. package/src/renderer/src/components/ImageStudioPanel.tsx +11 -1
  170. package/src/renderer/src/components/MintDashboard.tsx +63 -171
  171. package/src/renderer/src/components/PicturesLibrary.tsx +32 -8
  172. package/src/renderer/src/components/Settings/AgentsTab.tsx +362 -0
  173. package/src/renderer/src/components/Settings/AutomationTab.tsx +0 -22
  174. package/src/renderer/src/components/Settings/PluginsTab.tsx +221 -41
  175. package/src/renderer/src/components/SettingsWindow.tsx +54 -12
  176. package/src/renderer/src/components/WorkspacePanel.tsx +66 -9
  177. package/src/renderer/src/css/image-studio.css +6 -0
  178. package/src/renderer/src/css/styles.css +148 -11
  179. package/src/renderer/src/index.css +12 -1
  180. package/src/renderer/src/tauri.ts +169 -143
  181. package/src/renderer/src-web/agentProgress.ts +11 -39
  182. package/src/renderer/src-web/calculator.ts +3 -46
  183. package/src/renderer/src-web/components/ChatPanel.tsx +223 -1199
  184. package/src/renderer/src-web/components/ImageStudioPanel.tsx +11 -1
  185. package/src/renderer/src-web/components/MintDashboard.tsx +31 -172
  186. package/src/renderer/src-web/components/PicturesLibrary.tsx +23 -29
  187. package/src/renderer/src-web/components/Settings/AgentsTab.tsx +362 -0
  188. package/src/renderer/src-web/components/Settings/AutomationTab.tsx +0 -22
  189. package/src/renderer/src-web/components/Settings/PluginsTab.tsx +221 -41
  190. package/src/renderer/src-web/components/SettingsWindow.tsx +54 -12
  191. package/src/renderer/src-web/css/image-studio.css +6 -0
  192. package/src/renderer/src-web/css/styles.css +184 -12
  193. package/src/renderer/src-web/index.css +12 -1
  194. package/src/renderer/src-web/tauri.ts +204 -104
  195. package/src-tauri/src/browser.rs +1 -141
  196. package/src-tauri/src/headless.rs +3 -2
  197. package/src-tauri/src/lib.rs +254 -59
  198. package/src-tauri/src/webhooks.rs +1 -0
  199. package/src-tauri/src/workflows.rs +57 -4
  200. package/src-tauri/tauri.conf.json +1 -1
@@ -1,6 +1,6 @@
1
1
  import React, { useState, useEffect } from 'react'
2
2
  import { DEFAULT_CONFIG } from '../../components/SettingsWindow'
3
- import { listLearnedSkills, addLearnedSkill, deleteLearnedSkill, LearnedSkill } from '../../../src/tauri'
3
+ import { listLearnedSkills, addLearnedSkill, deleteLearnedSkill, LearnedSkill, detectSystemTools, DetectedTools } from '../../../src/tauri'
4
4
 
5
5
  interface PluginsTabProps {
6
6
  config: typeof DEFAULT_CONFIG
@@ -40,14 +40,49 @@ export default function PluginsTab({
40
40
  const [skillsLoading, setSkillsLoading] = useState(false)
41
41
  const [skillsError, setSkillsError] = useState('')
42
42
 
43
- // Load skills on mount
43
+ // Local state for auto-detected tools
44
+ const [detectedTools, setDetectedTools] = useState<DetectedTools>({
45
+ docker: false,
46
+ git: false,
47
+ gh: false,
48
+ node: false
49
+ })
50
+ const [detecting, setDetecting] = useState(false)
51
+
52
+ // Load skills and detect tools on mount
44
53
  useEffect(() => {
45
54
  fetchSkills()
55
+ detectTools()
46
56
  }, [])
47
57
 
58
+ const detectTools = async () => {
59
+ setDetecting(true)
60
+ try {
61
+ const tools = await detectSystemTools()
62
+ setDetectedTools(tools)
63
+ } catch (e) {
64
+ console.error("Failed to detect tools:", e)
65
+ } finally {
66
+ setDetecting(false)
67
+ }
68
+ }
69
+
70
+ const handleEnableTool = (name: string, command: string, args: string[]) => {
71
+ const updatedMcp = {
72
+ ...(config.mcpServers || {}),
73
+ [name]: {
74
+ command,
75
+ args,
76
+ env: {}
77
+ }
78
+ }
79
+ updateField('mcpServers', updatedMcp)
80
+ }
81
+
48
82
  const fetchSkills = async () => {
49
83
  try {
50
- const list = await listLearnedSkills()
84
+ const activeWorkspace = window.localStorage.getItem('mint:last-workspace-path') || undefined
85
+ const list = await listLearnedSkills(activeWorkspace)
51
86
  setSkills(list)
52
87
  } catch (e) {
53
88
  console.error("Failed to load skills:", e)
@@ -121,6 +156,79 @@ export default function PluginsTab({
121
156
  }
122
157
  ]
123
158
 
159
+ const mcpListItems: Array<{
160
+ name: string
161
+ command: string
162
+ args: string[]
163
+ icon: string
164
+ isEnabled: boolean
165
+ isConfigured: boolean
166
+ description: string
167
+ }> = []
168
+
169
+ Object.entries(config.mcpServers || {}).forEach(([name, srv]: [string, any]) => {
170
+ let icon = '⚙';
171
+ if (name === 'docker') icon = '🐳';
172
+ else if (name === 'git' || name === 'gitkraken') icon = '🐙';
173
+ else if (name === 'github') icon = '🐱';
174
+ else if (name === 'node') icon = '🟢';
175
+
176
+ mcpListItems.push({
177
+ name,
178
+ command: srv.command,
179
+ args: srv.args || [],
180
+ icon,
181
+ isEnabled: true,
182
+ isConfigured: true,
183
+ description: `Command: ${srv.command} ${(srv.args || []).join(' ')}`
184
+ });
185
+ });
186
+
187
+ if (detectedTools.docker && !config.mcpServers?.docker) {
188
+ mcpListItems.push({
189
+ name: 'docker',
190
+ command: 'npx',
191
+ args: ['-y', '@proxeus/mcp-docker-server'],
192
+ icon: '🐳',
193
+ isEnabled: false,
194
+ isConfigured: false,
195
+ description: 'Docker MCP Server (Discovered)'
196
+ });
197
+ }
198
+ if (detectedTools.git && !config.mcpServers?.git) {
199
+ mcpListItems.push({
200
+ name: 'git',
201
+ command: 'npx',
202
+ args: ['-y', '@modelcontextprotocol/server-git'],
203
+ icon: '🐙',
204
+ isEnabled: false,
205
+ isConfigured: false,
206
+ description: 'Git MCP Server (Discovered)'
207
+ });
208
+ }
209
+ if (detectedTools.gh && !config.mcpServers?.github) {
210
+ mcpListItems.push({
211
+ name: 'github',
212
+ command: 'npx',
213
+ args: ['-y', '@modelcontextprotocol/server-github'],
214
+ icon: '🐱',
215
+ isEnabled: false,
216
+ isConfigured: false,
217
+ description: 'GitHub MCP Server (Discovered)'
218
+ });
219
+ }
220
+ if (detectedTools.node && !config.mcpServers?.node) {
221
+ mcpListItems.push({
222
+ name: 'node',
223
+ command: 'npx',
224
+ args: ['-y', '@modelcontextprotocol/server-node'],
225
+ icon: '🟢',
226
+ isEnabled: false,
227
+ isConfigured: false,
228
+ description: 'NodeJS Runtime MCP Server (Discovered)'
229
+ });
230
+ }
231
+
124
232
  return (
125
233
  <div className="tab-pane active" style={{ display: 'flex', flexDirection: 'column', gap: '24px' }}>
126
234
  {/* ── Learned AI Skills ── */}
@@ -153,7 +261,7 @@ export default function PluginsTab({
153
261
  {skills.map((s) => (
154
262
  <div className="skill-card" key={s.id} style={{
155
263
  display: 'flex',
156
- alignItems: 'flex-start',
264
+ alignItems: 'center',
157
265
  justifyContent: 'space-between',
158
266
  padding: '16px 20px',
159
267
  border: '1px solid var(--border)',
@@ -162,7 +270,7 @@ export default function PluginsTab({
162
270
  gap: '16px'
163
271
  }}>
164
272
  <div style={{ flex: 1, minWidth: 0 }}>
165
- <div style={{ display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '6px' }}>
273
+ <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
166
274
  <span className="badge" style={{
167
275
  background: 'var(--accent)',
168
276
  color: '#fff',
@@ -171,24 +279,31 @@ export default function PluginsTab({
171
279
  padding: '2px 8px',
172
280
  borderRadius: '4px'
173
281
  }}>{s.name}</span>
282
+ {s.location && (
283
+ <span className="location-badge" style={{
284
+ background: s.location === 'workspace'
285
+ ? 'rgba(16, 185, 129, 0.15)'
286
+ : s.location === 'global'
287
+ ? 'rgba(59, 130, 246, 0.15)'
288
+ : 'rgba(139, 92, 246, 0.15)',
289
+ color: s.location === 'workspace'
290
+ ? '#10b981'
291
+ : s.location === 'global'
292
+ ? '#3b82f6'
293
+ : '#8b5cf6',
294
+ fontSize: '0.7rem',
295
+ fontWeight: '600',
296
+ padding: '2px 6px',
297
+ borderRadius: '4px',
298
+ textTransform: 'capitalize'
299
+ }}>
300
+ {s.location === 'database' ? 'Taught' : s.location}
301
+ </span>
302
+ )}
174
303
  <span style={{ fontSize: '0.8rem', color: 'var(--text-muted)', textOverflow: 'ellipsis', overflow: 'hidden', whiteSpace: 'nowrap' }}>
175
304
  Source: {s.sourcePath}
176
305
  </span>
177
306
  </div>
178
- <div style={{
179
- fontSize: '0.85rem',
180
- color: 'var(--text-main)',
181
- whiteSpace: 'pre-wrap',
182
- maxHeight: '120px',
183
- overflowY: 'auto',
184
- background: 'rgba(0,0,0,0.12)',
185
- padding: '10px 14px',
186
- borderRadius: '8px',
187
- fontFamily: 'monospace',
188
- lineHeight: '1.4'
189
- }}>
190
- {s.content}
191
- </div>
192
307
  </div>
193
308
  <button
194
309
  className="btn btn-danger"
@@ -254,33 +369,98 @@ export default function PluginsTab({
254
369
  </div>
255
370
 
256
371
  <div className="mcp-list">
257
- {Object.entries(config.mcpServers || {}).map(([name, srv]: [string, any]) => (
258
- <div className="plugin-card" key={name} style={{
259
- display: 'flex',
260
- alignItems: 'center',
261
- justifyContent: 'space-between',
262
- padding: '16px 20px',
263
- border: '1px solid var(--border)',
264
- borderRadius: '12px',
265
- background: 'var(--surface-bg)',
266
- marginBottom: '10px'
267
- }}>
268
- <div style={{ display: 'flex', alignItems: 'center', gap: '16px' }}>
269
- <div className="plugin-icon" style={{ fontSize: '1.5rem', width: '40px', height: '40px', display: 'grid', placeItems: 'center', background: 'var(--surface-strong)', borderRadius: '10px' }}>⚙</div>
270
- <div className="plugin-info">
271
- <div className="plugin-name" style={{ fontWeight: '600', color: 'var(--text-main)' }}>{name}</div>
272
- <div className="plugin-desc" style={{ fontFamily: 'monospace', fontSize: '0.8rem', color: 'var(--text-muted)' }}>
273
- Command: {srv.command} {srv.args?.join(' ')}
372
+ {mcpListItems.length === 0 ? (
373
+ <div style={{ padding: '20px', textAlign: 'center', color: 'var(--text-muted)' }}>
374
+ No MCP servers configured or discovered.
375
+ </div>
376
+ ) : (
377
+ mcpListItems.map((item) => (
378
+ <div
379
+ className="plugin-card"
380
+ key={item.name}
381
+ style={{
382
+ display: 'flex',
383
+ alignItems: 'center',
384
+ justifyContent: 'space-between',
385
+ padding: '16px 20px',
386
+ border: '1px solid var(--border)',
387
+ borderRadius: '12px',
388
+ background: item.isConfigured ? 'var(--surface-bg)' : 'rgba(16, 185, 129, 0.03)',
389
+ opacity: item.isConfigured ? 1 : 0.65,
390
+ marginBottom: '10px',
391
+ transition: 'all 0.2s'
392
+ }}
393
+ >
394
+ <div style={{ display: 'flex', alignItems: 'center', gap: '16px' }}>
395
+ <div className="plugin-icon" style={{ fontSize: '1.5rem', width: '40px', height: '40px', display: 'grid', placeItems: 'center', background: 'var(--surface-strong)', borderRadius: '10px' }}>
396
+ {item.icon}
397
+ </div>
398
+ <div className="plugin-info">
399
+ <div className="plugin-name" style={{ fontWeight: '600', color: 'var(--text-main)' }}>
400
+ {item.name} {!item.isConfigured && <span style={{ fontSize: '0.75rem', padding: '2px 6px', background: 'rgba(16, 185, 129, 0.15)', color: '#10b981', borderRadius: '4px', marginLeft: '6px' }}>Discovered</span>}
401
+ </div>
402
+ <div className="plugin-desc" style={{ fontFamily: 'monospace', fontSize: '0.8rem', color: 'var(--text-muted)' }}>
403
+ {item.description}
404
+ </div>
274
405
  </div>
275
406
  </div>
407
+ <div className="plugin-actions" style={{ display: 'flex', alignItems: 'center', gap: '16px' }}>
408
+ {item.isConfigured && (
409
+ <button
410
+ className="btn-icon-danger"
411
+ onClick={() => handleRemoveMcpServer(item.name)}
412
+ style={{
413
+ background: 'transparent',
414
+ border: 'none',
415
+ color: '#ef4444',
416
+ cursor: 'pointer',
417
+ padding: '6px',
418
+ display: 'flex',
419
+ alignItems: 'center',
420
+ justifyContent: 'center',
421
+ borderRadius: '6px',
422
+ transition: 'background 0.2s'
423
+ }}
424
+ title="Delete MCP Server"
425
+ >
426
+ <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
427
+ <polyline points="3 6 5 6 21 6"></polyline>
428
+ <path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path>
429
+ <line x1="10" y1="11" x2="10" y2="17"></line>
430
+ <line x1="14" y1="11" x2="14" y2="17"></line>
431
+ </svg>
432
+ </button>
433
+ )}
434
+ <label className="settings-toggle-switch">
435
+ <input
436
+ type="checkbox"
437
+ checked={item.isEnabled}
438
+ onChange={(e) => {
439
+ if (e.target.checked) {
440
+ handleEnableTool(item.name, item.command, item.args);
441
+ } else {
442
+ handleRemoveMcpServer(item.name);
443
+ }
444
+ }}
445
+ />
446
+ <span className="settings-toggle-slider" />
447
+ </label>
448
+ </div>
276
449
  </div>
277
- <div className="plugin-actions">
278
- <button className="btn btn-danger" onClick={() => handleRemoveMcpServer(name)} style={{ padding: '6px 12px', fontSize: '0.8rem', height: '34px' }}>Remove</button>
279
- </div>
280
- </div>
281
- ))}
450
+ ))
451
+ )}
282
452
  </div>
283
453
 
454
+ {/* Save settings alert */}
455
+ {((detectedTools.docker && !config.mcpServers?.docker) ||
456
+ (detectedTools.git && !config.mcpServers?.git) ||
457
+ (detectedTools.gh && !config.mcpServers?.github) ||
458
+ (detectedTools.node && !config.mcpServers?.node)) && (
459
+ <div style={{ marginTop: '12px', padding: '12px 16px', background: 'rgba(255,193,7,0.1)', border: '1px solid rgba(255,193,7,0.3)', borderRadius: '8px', fontSize: '0.8rem', color: '#ffb300', fontWeight: '500', display: 'flex', alignItems: 'center', gap: '8px' }}>
460
+ <span>⚠️ After toggling a plugin, please click the "Save Settings" button at the bottom of the window to persist changes.</span>
461
+ </div>
462
+ )}
463
+
284
464
  <div className="add-mcp-box" style={{
285
465
  marginTop: '20px',
286
466
  padding: '20px',
@@ -6,6 +6,7 @@ import AudioTab from './Settings/AudioTab'
6
6
  import AutomationTab from './Settings/AutomationTab'
7
7
  import ThemeTab from './Settings/ThemeTab'
8
8
  import PluginsTab from './Settings/PluginsTab'
9
+ import AgentsTab from './Settings/AgentsTab'
9
10
 
10
11
  export const DEFAULT_CONFIG = {
11
12
  theme: 'dark',
@@ -30,7 +31,7 @@ export const DEFAULT_CONFIG = {
30
31
  proactiveCooldown: 120,
31
32
  enableVoiceReply: true,
32
33
  enableCustomWorkflows: true,
33
- enableAgentCollaboration: true,
34
+ enableAgentCollaboration: false,
34
35
  ttsProvider: 'google',
35
36
  ttsVolume: 1.0,
36
37
  ttsSpeed: 1.0,
@@ -91,10 +92,40 @@ export const DEFAULT_CONFIG = {
91
92
  imageGenProvider: 'gemini' as 'gemini' | 'dalle' | 'stability' | 'ideogram' | 'replicate',
92
93
  stabilityApiKey: '',
93
94
  ideogramApiKey: '',
94
- replicateApiKey: ''
95
+ replicateApiKey: '',
96
+ // Multi-Agent Configuration
97
+ agents: [
98
+ {
99
+ id: 'planner',
100
+ name: 'Planner',
101
+ provider: 'gemini',
102
+ model: 'gemini-2.5-flash',
103
+ apiKey: '',
104
+ systemInstruction: 'You are the Planner agent. Your task is to analyze the user request, inspect the workspace structure, and design a step-by-step implementation plan. Create or update the implementation_plan.md file to document your proposal.',
105
+ enabled: true
106
+ },
107
+ {
108
+ id: 'coder',
109
+ name: 'Coder',
110
+ provider: 'gemini',
111
+ model: 'gemini-2.5-flash',
112
+ apiKey: '',
113
+ systemInstruction: 'You are the Coder agent. Your task is to implement the changes specified in the approved implementation plan. Read relevant files, write clean and efficient code, and run terminal commands to build or verify. Stay focused on execution.',
114
+ enabled: true
115
+ },
116
+ {
117
+ id: 'reviewer',
118
+ name: 'Reviewer',
119
+ provider: 'gemini',
120
+ model: 'gemini-2.5-flash',
121
+ apiKey: '',
122
+ systemInstruction: 'You are the Reviewer agent. Your task is to verify the code modifications made by the Coder. Run the automated tests, check lint errors, and ensure the implementation is correct and complete.',
123
+ enabled: true
124
+ }
125
+ ]
95
126
  }
96
127
 
97
- type TabType = 'sect-general' | 'sect-audio' | 'sect-automation' | 'sect-theme' | 'sect-plugins' | 'sect-shortcuts' | 'sect-memory'
128
+ type TabType = 'sect-general' | 'sect-audio' | 'sect-automation' | 'sect-theme' | 'sect-plugins' | 'sect-shortcuts' | 'sect-memory' | 'sect-agents'
98
129
 
99
130
  export const GEMINI_MODELS = [
100
131
  'gemini-2.5-flash',
@@ -157,15 +188,7 @@ export const LOCAL_MODELS = [
157
188
  'lmstudio-community/gemma-2-9b-it-GGUF'
158
189
  ]
159
190
 
160
- export const OLLAMA_MODELS = [
161
- 'llama3:latest',
162
- 'llama3.1:latest',
163
- 'llama3.2:latest',
164
- 'gemma2:latest',
165
- 'mistral:latest',
166
- 'phi3:latest',
167
- 'qwen2.5:latest'
168
- ]
191
+ export const OLLAMA_MODELS: string[] = []
169
192
 
170
193
  export default function SettingsWindow() {
171
194
  const [activeTab, setActiveTab] = useState<TabType>('sect-general')
@@ -624,6 +647,17 @@ export default function SettingsWindow() {
624
647
  </span>
625
648
  <strong>Plugins</strong>
626
649
  </button>
650
+ <button className={`tab-btn ${activeTab === 'sect-agents' ? 'active' : ''}`} onClick={() => setActiveTab('sect-agents')}>
651
+ <span style={{ display: 'inline-flex', alignItems: 'center' }}>
652
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
653
+ <path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path>
654
+ <circle cx="9" cy="7" r="4"></circle>
655
+ <path d="M23 21v-2a4 4 0 0 0-3-3.87"></path>
656
+ <path d="M16 3.13a4 4 0 0 1 0 7.75"></path>
657
+ </svg>
658
+ </span>
659
+ <strong>Multi-Agent (Beta)</strong>
660
+ </button>
627
661
  </nav>
628
662
 
629
663
  <div className="settings-content">
@@ -713,6 +747,14 @@ export default function SettingsWindow() {
713
747
  handleConnectPlugin={handleConnectPlugin}
714
748
  />
715
749
  )}
750
+
751
+ {activeTab === 'sect-agents' && (
752
+ <AgentsTab
753
+ config={config}
754
+ updateField={updateField}
755
+ dynamicOllamaModels={dynamicOllamaModels}
756
+ />
757
+ )}
716
758
  </div>
717
759
  </main>
718
760
 
@@ -725,3 +725,9 @@
725
725
  overflow-y: auto;
726
726
  }
727
727
  }
728
+
729
+ @media (max-width: 760px) {
730
+ .img-studio {
731
+ left: 0 !important;
732
+ }
733
+ }