## CHANGES

- Bumped Maestro version to 0.13.1 for the latest improvements 🚀
- Added Document Graph IPC handlers to enable live file watching 📈
- Introduced SSH Remote IPC handlers for managing saved SSH configurations 🛰️
- Added a dedicated SSH tab in Settings for cleaner navigation 🗂️
- Updated Settings keyboard tab-cycling to include the new SSH section ⌨️
- Refined Settings UI with a new Server icon for SSH tab branding 🖥️
- Moved SSH Remote hosts configuration into its own SSH Settings panel 🔐
This commit is contained in:
Pedram Amini
2025-12-29 17:21:37 -06:00
parent 43df1a42a6
commit 558419a755
3 changed files with 30 additions and 12 deletions

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "maestro",
"version": "0.13.0",
"version": "0.13.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "maestro",
"version": "0.13.0",
"version": "0.13.1",
"hasInstallScript": true,
"license": "AGPL 3.0",
"dependencies": {

View File

@@ -12,7 +12,7 @@ import { tunnelManager } from './tunnel-manager';
import { getThemeById } from './themes';
import Store from 'electron-store';
import { getHistoryManager } from './history-manager';
import { registerGitHandlers, registerAutorunHandlers, registerPlaybooksHandlers, registerHistoryHandlers, registerAgentsHandlers, registerProcessHandlers, registerPersistenceHandlers, registerSystemHandlers, registerClaudeHandlers, registerAgentSessionsHandlers, registerGroupChatHandlers, registerDebugHandlers, registerSpeckitHandlers, registerOpenSpecHandlers, registerContextHandlers, registerMarketplaceHandlers, registerStatsHandlers, setupLoggerEventForwarding, cleanupAllGroomingSessions, getActiveGroomingSessionCount } from './ipc/handlers';
import { registerGitHandlers, registerAutorunHandlers, registerPlaybooksHandlers, registerHistoryHandlers, registerAgentsHandlers, registerProcessHandlers, registerPersistenceHandlers, registerSystemHandlers, registerClaudeHandlers, registerAgentSessionsHandlers, registerGroupChatHandlers, registerDebugHandlers, registerSpeckitHandlers, registerOpenSpecHandlers, registerContextHandlers, registerMarketplaceHandlers, registerStatsHandlers, registerDocumentGraphHandlers, registerSshRemoteHandlers, setupLoggerEventForwarding, cleanupAllGroomingSessions, getActiveGroomingSessionCount } from './ipc/handlers';
import { initializeStatsDB, closeStatsDB, getStatsDB } from './stats-db';
import { groupChatEmitters } from './ipc/handlers/groupChat';
import { routeModeratorResponse, routeAgentResponse, setGetSessionsCallback, setGetCustomEnvVarsCallback, setGetAgentConfigCallback, markParticipantResponded, spawnModeratorSynthesis, getGroupChatReadOnlyState, respawnParticipantWithRecovery } from './group-chat/group-chat-router';
@@ -1110,6 +1110,17 @@ function setupIpcHandlers() {
settingsStore: store,
});
// Register Document Graph handlers for file watching
registerDocumentGraphHandlers({
getMainWindow: () => mainWindow,
app,
});
// Register SSH Remote handlers for managing SSH configurations
registerSshRemoteHandlers({
settingsStore: store,
});
// Set up callback for group chat router to lookup sessions for auto-add @mentions
setGetSessionsCallback(() => {
const sessions = sessionsStore.get('sessions', []);

View File

@@ -1,5 +1,5 @@
import React, { useState, useEffect, useRef, memo } from 'react';
import { X, Key, Moon, Sun, Keyboard, Check, Terminal, Bell, Cpu, Settings, Palette, Sparkles, History, Download, Bug, Cloud, FolderSync, RotateCcw, Folder, ChevronDown, Plus, Trash2, Brain, AlertTriangle, FlaskConical, Database } from 'lucide-react';
import { X, Key, Moon, Sun, Keyboard, Check, Terminal, Bell, Cpu, Settings, Palette, Sparkles, History, Download, Bug, Cloud, FolderSync, RotateCcw, Folder, ChevronDown, Plus, Trash2, Brain, AlertTriangle, FlaskConical, Database, Server } from 'lucide-react';
import { useSettings } from '../hooks';
import type { Theme, ThemeColors, ThemeId, Shortcut, ShellInfo, CustomAICommand, LLMProvider } from '../types';
import { CustomThemeBuilder } from './CustomThemeBuilder';
@@ -220,7 +220,7 @@ interface SettingsModalProps {
setCrashReportingEnabled: (value: boolean) => void;
customAICommands: CustomAICommand[];
setCustomAICommands: (commands: CustomAICommand[]) => void;
initialTab?: 'general' | 'llm' | 'shortcuts' | 'theme' | 'notifications' | 'aicommands';
initialTab?: 'general' | 'llm' | 'shortcuts' | 'theme' | 'notifications' | 'aicommands' | 'ssh';
hasNoAgents?: boolean;
onThemeImportError?: (message: string) => void;
onThemeImportSuccess?: (message: string) => void;
@@ -247,7 +247,7 @@ export const SettingsModal = memo(function SettingsModal(props: SettingsModalPro
setDefaultStatsTimeRange,
} = useSettings();
const [activeTab, setActiveTab] = useState<'general' | 'llm' | 'shortcuts' | 'theme' | 'notifications' | 'aicommands'>('general');
const [activeTab, setActiveTab] = useState<'general' | 'llm' | 'shortcuts' | 'theme' | 'notifications' | 'aicommands' | 'ssh'>('general');
const [systemFonts, setSystemFonts] = useState<string[]>([]);
const [customFonts, setCustomFonts] = useState<string[]>([]);
const [fontLoading, setFontLoading] = useState(false);
@@ -375,9 +375,9 @@ export const SettingsModal = memo(function SettingsModal(props: SettingsModalPro
if (!isOpen) return;
const handleTabNavigation = (e: KeyboardEvent) => {
const tabs: Array<'general' | 'llm' | 'shortcuts' | 'theme' | 'notifications' | 'aicommands'> = FEATURE_FLAGS.LLM_SETTINGS
? ['general', 'llm', 'shortcuts', 'theme', 'notifications', 'aicommands']
: ['general', 'shortcuts', 'theme', 'notifications', 'aicommands'];
const tabs: Array<'general' | 'llm' | 'shortcuts' | 'theme' | 'notifications' | 'aicommands' | 'ssh'> = FEATURE_FLAGS.LLM_SETTINGS
? ['general', 'llm', 'shortcuts', 'theme', 'notifications', 'aicommands', 'ssh']
: ['general', 'shortcuts', 'theme', 'notifications', 'aicommands', 'ssh'];
const currentIndex = tabs.indexOf(activeTab);
if ((e.metaKey || e.ctrlKey) && e.shiftKey && e.key === '[') {
@@ -764,6 +764,10 @@ export const SettingsModal = memo(function SettingsModal(props: SettingsModalPro
<Cpu className="w-4 h-4" />
{activeTab === 'aicommands' && <span>AI Commands</span>}
</button>
<button onClick={() => setActiveTab('ssh')} className={`px-4 py-4 text-sm font-bold border-b-2 ${activeTab === 'ssh' ? 'border-indigo-500' : 'border-transparent'} flex items-center gap-2`} tabIndex={-1} title="SSH">
<Server className="w-4 h-4" />
{activeTab === 'ssh' && <span>SSH</span>}
</button>
<div className="flex-1 flex justify-end items-center pr-4">
<button onClick={onClose} tabIndex={-1}><X className="w-5 h-5 opacity-50 hover:opacity-100" /></button>
</div>
@@ -1592,9 +1596,6 @@ export const SettingsModal = memo(function SettingsModal(props: SettingsModalPro
</div>
</div>
{/* SSH Remote Hosts */}
<SshRemotesSection theme={theme} />
{/* Settings Storage Location */}
<div
className="flex items-start gap-3 p-4 rounded-xl border relative"
@@ -1988,6 +1989,12 @@ export const SettingsModal = memo(function SettingsModal(props: SettingsModalPro
<OpenSpecCommandsPanel theme={theme} />
</div>
)}
{activeTab === 'ssh' && (
<div className="space-y-5">
<SshRemotesSection theme={theme} />
</div>
)}
</div>
</div>
</div>