diff --git a/docs/configuration.md b/docs/configuration.md
index 1ee65512..78f6a6f4 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -12,7 +12,7 @@ Settings are organized into tabs:
| Tab | Contents |
|-----|----------|
-| **General** | Shell configuration, input send behavior, default toggles (history, thinking), automatic tab naming, power management, updates, privacy, usage stats, storage location |
+| **General** | About Me (conductor profile), shell configuration, input send behavior, default toggles (history, thinking), automatic tab naming, power management, updates, privacy, usage stats, storage location |
| **Display** | Font family and size, terminal width, log level and buffer, max output lines per response, document graph settings, context window warnings |
| **Shortcuts** | Customize keyboard shortcuts (see [Keyboard Shortcuts](./keyboard-shortcuts)) |
| **Themes** | Dark, light, and vibe mode themes, custom theme builder with import/export |
diff --git a/docs/slash-commands.md b/docs/slash-commands.md
index 4aaafae0..dc283706 100644
--- a/docs/slash-commands.md
+++ b/docs/slash-commands.md
@@ -44,6 +44,12 @@ Create your own slash commands in **Settings → AI Commands**. Each command has
Commands support **template variables** that are automatically substituted at runtime:
+### Conductor Variables
+
+| Variable | Description |
+|----------|-------------|
+| `{{CONDUCTOR_PROFILE}}` | Your "About Me" profile from Settings → General. Tells agents about your background, preferences, and communication style. |
+
### Agent Variables
| Variable | Description |
diff --git a/src/__tests__/renderer/components/SettingsModal.test.tsx b/src/__tests__/renderer/components/SettingsModal.test.tsx
index 3192a233..d858f297 100644
--- a/src/__tests__/renderer/components/SettingsModal.test.tsx
+++ b/src/__tests__/renderer/components/SettingsModal.test.tsx
@@ -68,6 +68,10 @@ vi.mock('../../../renderer/components/CustomThemeBuilder', () => ({
// Mock useSettings hook (used for context management settings and SSH remote ignore settings)
vi.mock('../../../renderer/hooks/settings/useSettings', () => ({
useSettings: () => ({
+ // Conductor profile settings
+ conductorProfile: '',
+ setConductorProfile: vi.fn(),
+ // Context management settings
contextManagementSettings: {
autoGroomContexts: true,
maxContextTokens: 100000,
diff --git a/src/__tests__/renderer/components/Wizard/WizardKeyboardNavigation.test.tsx b/src/__tests__/renderer/components/Wizard/WizardKeyboardNavigation.test.tsx
index 421a025c..dcfcce96 100644
--- a/src/__tests__/renderer/components/Wizard/WizardKeyboardNavigation.test.tsx
+++ b/src/__tests__/renderer/components/Wizard/WizardKeyboardNavigation.test.tsx
@@ -154,6 +154,12 @@ const mockMaestro = {
shell: {
openExternal: vi.fn(),
},
+ sshRemote: {
+ getConfigs: vi.fn().mockResolvedValue({ success: true, configs: [] }),
+ },
+ sessions: {
+ getAll: vi.fn().mockResolvedValue([]),
+ },
};
// Mock theme
diff --git a/src/__tests__/renderer/components/Wizard/WizardThemeStyles.test.tsx b/src/__tests__/renderer/components/Wizard/WizardThemeStyles.test.tsx
index 74043a24..e9cbfb41 100644
--- a/src/__tests__/renderer/components/Wizard/WizardThemeStyles.test.tsx
+++ b/src/__tests__/renderer/components/Wizard/WizardThemeStyles.test.tsx
@@ -159,6 +159,12 @@ const mockMaestro = {
fs: {
readFile: vi.fn(),
},
+ sshRemote: {
+ getConfigs: vi.fn().mockResolvedValue({ success: true, configs: [] }),
+ },
+ sessions: {
+ getAll: vi.fn().mockResolvedValue([]),
+ },
};
// Helper to render with required providers
diff --git a/src/__tests__/shared/templateVariables.test.ts b/src/__tests__/shared/templateVariables.test.ts
index 7d27a9d6..6d1d8c3e 100644
--- a/src/__tests__/shared/templateVariables.test.ts
+++ b/src/__tests__/shared/templateVariables.test.ts
@@ -58,6 +58,11 @@ describe('TEMPLATE_VARIABLES constant', () => {
});
});
+ it('should include conductor variables', () => {
+ const variables = TEMPLATE_VARIABLES.map((v) => v.variable);
+ expect(variables).toContain('{{CONDUCTOR_PROFILE}}');
+ });
+
it('should include key agent variables', () => {
const variables = TEMPLATE_VARIABLES.map((v) => v.variable);
expect(variables).toContain('{{AGENT_NAME}}');
@@ -138,6 +143,24 @@ describe('substituteTemplateVariables', () => {
vi.useRealTimers();
});
+ describe('Conductor Variables', () => {
+ it('should replace {{CONDUCTOR_PROFILE}} with conductorProfile', () => {
+ const context = createTestContext({
+ conductorProfile: 'Senior developer specializing in TypeScript and React',
+ });
+ const result = substituteTemplateVariables('Profile: {{CONDUCTOR_PROFILE}}', context);
+ expect(result).toBe('Profile: Senior developer specializing in TypeScript and React');
+ });
+
+ it('should replace {{CONDUCTOR_PROFILE}} with empty string when conductorProfile is undefined', () => {
+ const context = createTestContext({
+ conductorProfile: undefined,
+ });
+ const result = substituteTemplateVariables('Profile: {{CONDUCTOR_PROFILE}}', context);
+ expect(result).toBe('Profile: ');
+ });
+ });
+
describe('Agent Variables', () => {
it('should replace {{AGENT_NAME}} with session.name', () => {
const context = createTestContext({
diff --git a/src/prompts/group-chat-moderator-system.md b/src/prompts/group-chat-moderator-system.md
index 8f692a36..16b0d403 100644
--- a/src/prompts/group-chat-moderator-system.md
+++ b/src/prompts/group-chat-moderator-system.md
@@ -1,4 +1,10 @@
-You are a Group Chat Moderator in Maestro, a multi-agent orchestration tool. Your role is to:
+You are a Group Chat Moderator in Maestro, a multi-agent orchestration tool.
+
+## Conductor Profile
+
+{{CONDUCTOR_PROFILE}}
+
+Your role is to:
1. **Assist the user directly** - You are a capable AI assistant. For simple questions or tasks, respond directly without delegating to other agents.
diff --git a/src/prompts/maestro-system-prompt.md b/src/prompts/maestro-system-prompt.md
index 93555f5c..13447a2c 100644
--- a/src/prompts/maestro-system-prompt.md
+++ b/src/prompts/maestro-system-prompt.md
@@ -2,6 +2,10 @@
You are **{{AGENT_NAME}}**, powered by **{{TOOL_TYPE}}**, operating as a Maestro-managed AI coding agent.
+## Conductor Profile
+
+{{CONDUCTOR_PROFILE}}
+
## About Maestro
Maestro is an Electron desktop application for managing multiple AI coding assistants simultaneously with a keyboard-first interface. For more information:
@@ -27,8 +31,11 @@ Your session history is stored at `{{AGENT_HISTORY_PATH}}`. When you need contex
- `timestamp`: When the task was completed (Unix ms)
- `type`: `AUTO` (automated) or `USER` (interactive)
- `success`: Whether the task succeeded
+- `fullResponse`: Complete AI response text (for detailed context)
+- `elapsedTimeMs`: How long the task took
+- `contextUsage`: Context window usage percentage at completion
-To recall recent work, read the file and scan the most recent entries by timestamp.
+To recall recent work, read the file and scan the most recent entries by timestamp. Use `summary` for quick scanning and `fullResponse` when you need detailed context about what was done.
## Auto-run Documents
diff --git a/src/prompts/wizard-inline-system.md b/src/prompts/wizard-inline-system.md
index cb9314c5..af9f69f8 100644
--- a/src/prompts/wizard-inline-system.md
+++ b/src/prompts/wizard-inline-system.md
@@ -1,9 +1,25 @@
You are a planning assistant helping in an existing Maestro session for "{{PROJECT_NAME}}".
+## Conductor Profile
+
+{{CONDUCTOR_PROFILE}}
+
## Your Role
You are helping plan work in an active session. The user has an established project context and wants to create or extend a Playbook.
+## Task Recall
+
+Your session history is stored at `{{AGENT_HISTORY_PATH}}`. When you need context about previously completed work in this project, read this JSON file and parse the `entries` array. Each entry contains:
+- `summary`: Brief description of the task
+- `timestamp`: When the task was completed (Unix ms)
+- `type`: `AUTO` (automated) or `USER` (interactive)
+- `success`: Whether the task succeeded
+- `fullResponse`: Complete AI response text (for detailed context)
+- `elapsedTimeMs`: How long the task took
+
+To recall recent work, read the file and scan the most recent entries by timestamp. Use `summary` for quick scanning and `fullResponse` when you need detailed context about what has already been accomplished.
+
## File Access Restrictions
**WRITE ACCESS (Limited):**
diff --git a/src/prompts/wizard-system.md b/src/prompts/wizard-system.md
index af3e2e67..e8e8c5f5 100644
--- a/src/prompts/wizard-system.md
+++ b/src/prompts/wizard-system.md
@@ -1,9 +1,25 @@
You are a friendly project discovery assistant helping to set up "{{PROJECT_NAME}}".
+## Conductor Profile
+
+{{CONDUCTOR_PROFILE}}
+
## Your Role
You are 🎼 Maestro's onboarding assistant, helping the user define their project so we can create an actionable plan.
+## Task Recall
+
+Your session history is stored at `{{AGENT_HISTORY_PATH}}`. When you need context about previously completed work in this project, read this JSON file and parse the `entries` array. Each entry contains:
+- `summary`: Brief description of the task
+- `timestamp`: When the task was completed (Unix ms)
+- `type`: `AUTO` (automated) or `USER` (interactive)
+- `success`: Whether the task succeeded
+- `fullResponse`: Complete AI response text (for detailed context)
+- `elapsedTimeMs`: How long the task took
+
+To recall recent work, read the file and scan the most recent entries by timestamp. Use `summary` for quick scanning and `fullResponse` when you need detailed context about what has already been accomplished.
+
## File Access Restrictions
**WRITE ACCESS (Limited):**
diff --git a/src/renderer/App.tsx b/src/renderer/App.tsx
index 1ae69f95..a54fa61f 100644
--- a/src/renderer/App.tsx
+++ b/src/renderer/App.tsx
@@ -453,6 +453,7 @@ function MaestroConsoleInner() {
const settings = useSettings();
const {
settingsLoaded,
+ conductorProfile,
llmProvider,
setLlmProvider,
modelSlug,
@@ -4551,6 +4552,7 @@ You are taking over this conversation. Based on the context above, provide a bri
const substitutedSystemPrompt = substituteTemplateVariables(maestroSystemPrompt, {
session: targetSession,
gitBranch,
+ conductorProfile,
});
effectivePrompt = `${substitutedSystemPrompt}\n\n---\n\n# User Request\n\n${effectivePrompt}`;
}
@@ -7497,7 +7499,8 @@ You are taking over this conversation. Based on the context above, provide a bri
activeTab.id, // Tab ID for per-tab isolation
activeSession.id, // Session ID for playbook creation
activeSession.autoRunFolderPath, // User-configured Auto Run folder path (if set)
- activeSession.sessionSshRemoteConfig // SSH remote config for remote execution
+ activeSession.sessionSshRemoteConfig, // SSH remote config for remote execution
+ conductorProfile // Conductor profile (user's About Me from settings)
);
// Rename the tab to "Wizard" immediately when wizard starts
@@ -7526,7 +7529,7 @@ You are taking over this conversation. Based on the context above, provide a bri
};
addLogToActiveTab(activeSession.id, wizardLog);
},
- [activeSession, startInlineWizard, addLogToActiveTab]
+ [activeSession, startInlineWizard, addLogToActiveTab, conductorProfile]
);
// Launch wizard in a new tab - triggered from Auto Run panel button
@@ -7580,7 +7583,8 @@ You are taking over this conversation. Based on the context above, provide a bri
newTab.id,
activeSession.id,
activeSession.autoRunFolderPath, // User-configured Auto Run folder path (if set)
- activeSession.sessionSshRemoteConfig // SSH remote config for remote execution
+ activeSession.sessionSshRemoteConfig, // SSH remote config for remote execution
+ conductorProfile // Conductor profile (user's About Me from settings)
);
// Show a system log entry
@@ -7597,6 +7601,7 @@ You are taking over this conversation. Based on the context above, provide a bri
defaultShowThinking,
startInlineWizard,
addLogToTab,
+ conductorProfile,
]);
// Determine if wizard is active for the current tab
@@ -7634,6 +7639,7 @@ You are taking over this conversation. Based on the context above, provide a bri
isWizardActive: isWizardActiveForCurrentTab,
onSkillsCommand: handleSkillsCommand,
automaticTabNamingEnabled,
+ conductorProfile,
});
// Auto-send context when a tab with autoSendOnActivate becomes active
@@ -10113,6 +10119,7 @@ You are taking over this conversation. Based on the context above, provide a bri
promptToSend = substituteTemplateVariables(matchingCommand.prompt, {
session,
gitBranch,
+ conductorProfile,
});
commandMetadata = {
command: matchingCommand.command,
@@ -10411,6 +10418,7 @@ You are taking over this conversation. Based on the context above, provide a bri
const substitutedSystemPrompt = substituteTemplateVariables(maestroSystemPrompt, {
session,
gitBranch,
+ conductorProfile,
});
// Prepend system prompt to user's message
@@ -10482,6 +10490,7 @@ You are taking over this conversation. Based on the context above, provide a bri
const substitutedPrompt = substituteTemplateVariables(promptWithArgs, {
session,
gitBranch,
+ conductorProfile,
});
// For NEW sessions (no agentSessionId), prepend Maestro system prompt
@@ -10494,6 +10503,7 @@ You are taking over this conversation. Based on the context above, provide a bri
const substitutedSystemPrompt = substituteTemplateVariables(maestroSystemPrompt, {
session,
gitBranch,
+ conductorProfile,
});
// Prepend system prompt to command's prompt (for agent only)
diff --git a/src/renderer/components/MainPanel.tsx b/src/renderer/components/MainPanel.tsx
index a00d8e9b..d34daf4a 100644
--- a/src/renderer/components/MainPanel.tsx
+++ b/src/renderer/components/MainPanel.tsx
@@ -977,7 +977,7 @@ export const MainPanel = React.memo(
{/* Hide branch name text at narrow widths, show on hover via title */}
{!useIconOnlyGitBranch && (
-
+
{gitInfo?.branch || 'GIT'}
)}
diff --git a/src/renderer/components/SettingsModal.tsx b/src/renderer/components/SettingsModal.tsx
index 63032f50..89d79f8d 100644
--- a/src/renderer/components/SettingsModal.tsx
+++ b/src/renderer/components/SettingsModal.tsx
@@ -31,6 +31,7 @@ import {
Monitor,
PartyPopper,
Tag,
+ User,
} from 'lucide-react';
import { useSettings } from '../hooks';
import type {
@@ -283,6 +284,9 @@ export const SettingsModal = memo(function SettingsModal(props: SettingsModalPro
// Context management settings from useSettings hook
const {
+ // Conductor Profile (About Me)
+ conductorProfile,
+ setConductorProfile,
contextManagementSettings,
updateContextManagementSettings,
// Document Graph settings
@@ -951,6 +955,44 @@ export const SettingsModal = memo(function SettingsModal(props: SettingsModalPro
{activeTab === 'general' && (
+ {/* About Me (Conductor Profile) */}
+
+
+
+ Tell us a little about yourself so that agents created under Maestro know how to
+ work and communicate with you. As the conductor, you orchestrate the symphony of AI
+ agents. (Optional, max 1000 characters)
+
+
+
+
+
{/* Default Shell */}
- {/* Section 2: Note box - centered in available space */}
-
-
-
-
- Note: The new agent wizard captures
- application inputs until complete. For a lighter touch, create a new agent then run{' '}
-
- /wizard
-
- {' '}or click the{' '}
-
- {' '}button in the Auto Run panel. The in-tab wizard runs alongside your other work.
-
+ {/* Section 2: Note box - only shown if user has existing agents */}
+ {hasExistingAgents && (
+
+
+
+
+ Note: The new agent wizard captures
+ application inputs until complete. For a lighter touch, create a new agent then run{' '}
+
+ /wizard
+
+ {' '}or click the{' '}
+
+ {' '}button in the Auto Run panel. The in-tab wizard runs alongside your other work.
+
+
-
+ )}
{/* Section 3: Agent Grid or Connection Error */}
{sshConnectionError ? (
diff --git a/src/renderer/components/Wizard/services/wizardPrompts.ts b/src/renderer/components/Wizard/services/wizardPrompts.ts
index 1fb36c74..309adf10 100644
--- a/src/renderer/components/Wizard/services/wizardPrompts.ts
+++ b/src/renderer/components/Wizard/services/wizardPrompts.ts
@@ -60,6 +60,10 @@ export interface SystemPromptConfig {
existingDocs?: ExistingDocument[];
/** Auto Run folder path (defaults to agentPath/Auto Run Docs if not provided) */
autoRunFolderPath?: string;
+ /** History file path for task recall (optional, enables AI to recall recent work) */
+ historyFilePath?: string;
+ /** Conductor profile (user's About Me from settings) */
+ conductorProfile?: string;
}
/**
@@ -112,7 +116,7 @@ export const READY_CONFIDENCE_THRESHOLD = 80;
* @returns The complete system prompt for the agent
*/
export function generateSystemPrompt(config: SystemPromptConfig): string {
- const { agentName, agentPath, existingDocs, autoRunFolderPath } = config;
+ const { agentName, agentPath, existingDocs, autoRunFolderPath, historyFilePath, conductorProfile } = config;
const projectName = agentName || 'this project';
// Default Auto Run folder to standard location under working directory
@@ -140,6 +144,7 @@ export function generateSystemPrompt(config: SystemPromptConfig): string {
// Build template context for remaining variables (date/time, etc.)
// Include autoRunFolderPath so {{AUTORUN_FOLDER}} is properly substituted
+ // Include historyFilePath for {{AGENT_HISTORY_PATH}} task recall
const templateContext: TemplateContext = {
session: {
id: 'wizard',
@@ -150,6 +155,8 @@ export function generateSystemPrompt(config: SystemPromptConfig): string {
autoRunFolderPath: effectiveAutoRunFolder,
},
autoRunFolder: effectiveAutoRunFolder,
+ historyFilePath: historyFilePath,
+ conductorProfile: conductorProfile,
};
// Substitute any remaining template variables using the central function
diff --git a/src/renderer/hooks/input/useInputProcessing.ts b/src/renderer/hooks/input/useInputProcessing.ts
index f0ba49fa..9ff5f7f3 100644
--- a/src/renderer/hooks/input/useInputProcessing.ts
+++ b/src/renderer/hooks/input/useInputProcessing.ts
@@ -72,6 +72,8 @@ export interface UseInputProcessingDeps {
onSkillsCommand?: () => Promise;
/** Whether automatic tab naming is enabled */
automaticTabNamingEnabled?: boolean;
+ /** Conductor profile (user's About Me from settings) */
+ conductorProfile?: string;
}
/**
@@ -128,6 +130,7 @@ export function useInputProcessing(deps: UseInputProcessingDeps): UseInputProces
isWizardActive,
onSkillsCommand,
automaticTabNamingEnabled,
+ conductorProfile,
} = deps;
// Ref for the processInput function so external code can access the latest version
@@ -239,6 +242,7 @@ export function useInputProcessing(deps: UseInputProcessingDeps): UseInputProces
substituteTemplateVariables(matchingCustomCommand.prompt, {
session: activeSession,
gitBranch,
+ conductorProfile,
});
// ALWAYS queue slash commands - they execute in order like write messages
@@ -903,6 +907,7 @@ export function useInputProcessing(deps: UseInputProcessingDeps): UseInputProces
session: freshSession,
gitBranch,
historyFilePath,
+ conductorProfile,
});
// Prepend system prompt to user's message
diff --git a/src/renderer/hooks/settings/useSettings.ts b/src/renderer/hooks/settings/useSettings.ts
index d18bb4ef..06db6e37 100644
--- a/src/renderer/hooks/settings/useSettings.ts
+++ b/src/renderer/hooks/settings/useSettings.ts
@@ -126,6 +126,10 @@ export interface UseSettingsReturn {
// Loading state
settingsLoaded: boolean;
+ // Conductor Profile (About Me)
+ conductorProfile: string;
+ setConductorProfile: (value: string) => void;
+
// LLM settings
llmProvider: LLMProvider;
modelSlug: string;
@@ -360,6 +364,9 @@ export function useSettings(): UseSettingsReturn {
// Loading state
const [settingsLoaded, setSettingsLoaded] = useState(false);
+ // Conductor Profile (About Me) - optional, up to 1000 characters
+ const [conductorProfile, setConductorProfileState] = useState('');
+
// LLM Config
const [llmProvider, setLlmProviderState] = useState('openrouter');
const [modelSlug, setModelSlugState] = useState('anthropic/claude-3.5-sonnet');
@@ -517,6 +524,15 @@ export function useSettings(): UseSettingsReturn {
// Wrapper functions that persist to electron-store
// PERF: All wrapped in useCallback to prevent re-renders
+
+ // Conductor Profile (About Me)
+ const setConductorProfile = useCallback((value: string) => {
+ // Enforce 1000 character limit
+ const trimmed = value.slice(0, 1000);
+ setConductorProfileState(trimmed);
+ window.maestro.settings.set('conductorProfile', trimmed);
+ }, []);
+
const setLlmProvider = useCallback((value: LLMProvider) => {
setLlmProviderState(value);
window.maestro.settings.set('llmProvider', value);
@@ -1344,6 +1360,7 @@ export function useSettings(): UseSettingsReturn {
const allSettings = (await window.maestro.settings.getAll()) as Record;
// Extract settings from the batch response
+ const savedConductorProfile = allSettings['conductorProfile'];
const savedEnterToSendAI = allSettings['enterToSendAI'];
const savedEnterToSendTerminal = allSettings['enterToSendTerminal'];
const savedDefaultSaveToHistory = allSettings['defaultSaveToHistory'];
@@ -1411,6 +1428,9 @@ export function useSettings(): UseSettingsReturn {
const savedFileTabAutoRefreshEnabled = allSettings['fileTabAutoRefreshEnabled'];
const savedSuppressWindowsWarning = allSettings['suppressWindowsWarning'];
+ // Conductor Profile (About Me)
+ if (savedConductorProfile !== undefined) setConductorProfileState(savedConductorProfile as string);
+
if (savedEnterToSendAI !== undefined) setEnterToSendAIState(savedEnterToSendAI as boolean);
if (savedEnterToSendTerminal !== undefined)
setEnterToSendTerminalState(savedEnterToSendTerminal as boolean);
@@ -1814,6 +1834,8 @@ export function useSettings(): UseSettingsReturn {
return useMemo(
() => ({
settingsLoaded,
+ conductorProfile,
+ setConductorProfile,
llmProvider,
modelSlug,
apiKey,
@@ -1963,6 +1985,7 @@ export function useSettings(): UseSettingsReturn {
[
// State values
settingsLoaded,
+ conductorProfile,
llmProvider,
modelSlug,
apiKey,
@@ -2008,6 +2031,7 @@ export function useSettings(): UseSettingsReturn {
firstAutoRunCompleted,
onboardingStats,
// Setter functions (stable via useCallback)
+ setConductorProfile,
setLlmProvider,
setModelSlug,
setApiKey,
diff --git a/src/renderer/hooks/useInlineWizard.ts b/src/renderer/hooks/useInlineWizard.ts
index 9c88f142..913fffa0 100644
--- a/src/renderer/hooks/useInlineWizard.ts
+++ b/src/renderer/hooks/useInlineWizard.ts
@@ -149,6 +149,10 @@ export interface InlineWizardState {
remoteId: string | null;
workingDirOverride?: string;
};
+ /** Conductor profile (user's About Me from settings) */
+ conductorProfile?: string;
+ /** History file path for task recall (fetched once during startWizard) */
+ historyFilePath?: string;
}
/**
@@ -206,6 +210,7 @@ export interface UseInlineWizardReturn {
* @param sessionId - The session ID for playbook creation
* @param autoRunFolderPath - User-configured Auto Run folder path (if set, overrides default projectPath/Auto Run Docs)
* @param sessionSshRemoteConfig - SSH remote configuration (for remote execution)
+ * @param conductorProfile - Conductor profile (user's About Me from settings)
*/
startWizard: (
naturalLanguageInput?: string,
@@ -220,7 +225,8 @@ export interface UseInlineWizardReturn {
enabled: boolean;
remoteId: string | null;
workingDirOverride?: string;
- }
+ },
+ conductorProfile?: string
) => Promise;
/** End the wizard and restore previous UI state */
endWizard: () => Promise;
@@ -467,7 +473,8 @@ export function useInlineWizard(): UseInlineWizardReturn {
enabled: boolean;
remoteId: string | null;
workingDirOverride?: string;
- }
+ },
+ conductorProfile?: string
): Promise => {
// Tab ID is required for per-tab wizard management
const effectiveTabId = tabId || 'default';
@@ -524,9 +531,23 @@ export function useInlineWizard(): UseInlineWizardReturn {
subfolderPath: null,
autoRunFolderPath: effectiveAutoRunFolderPath,
sessionSshRemoteConfig,
+ conductorProfile,
}));
try {
+ // Step 0: Fetch history file path for task recall (if session ID is available)
+ // This is done early so it's available for both conversation session and state
+ let historyFilePath: string | undefined;
+ if (sessionId) {
+ try {
+ const fetchedPath = await window.maestro.history.getFilePath(sessionId);
+ historyFilePath = fetchedPath ?? undefined; // Convert null to undefined
+ } catch {
+ // History file path not available - continue without it
+ logger.debug('Could not fetch history file path', '[InlineWizard]', { sessionId });
+ }
+ }
+
// Step 1: Check for existing Auto Run documents in the configured folder
// Use the effective Auto Run folder path (user-configured or default)
let hasExistingDocs = false;
@@ -591,6 +612,7 @@ export function useInlineWizard(): UseInlineWizardReturn {
supportedWizardAgents.includes(agentType) &&
effectiveAutoRunFolderPath
) {
+ // historyFilePath was fetched in Step 0 above
const session = startInlineWizardConversation({
mode,
agentType,
@@ -600,6 +622,8 @@ export function useInlineWizard(): UseInlineWizardReturn {
existingDocs: docsWithContent.length > 0 ? docsWithContent : undefined,
autoRunFolderPath: effectiveAutoRunFolderPath,
sessionSshRemoteConfig,
+ conductorProfile,
+ historyFilePath,
});
// Store conversation session per-tab
@@ -629,12 +653,14 @@ export function useInlineWizard(): UseInlineWizardReturn {
}
// Update state with parsed results
+ // Store historyFilePath so it's available for setMode if user is in 'ask' mode
setTabState(effectiveTabId, (prev) => ({
...prev,
isInitializing: false,
mode,
goal,
existingDocuments: existingDocs,
+ historyFilePath,
}));
} catch (error) {
// Handle any errors during initialization
@@ -747,6 +773,7 @@ export function useInlineWizard(): UseInlineWizardReturn {
effectiveAutoRunFolderPath
) {
console.log('[useInlineWizard] Auto-creating session for direct message in ask mode');
+ // Use historyFilePath from state (fetched during startWizard)
session = startInlineWizardConversation({
mode: 'new',
agentType: currentState.agentType,
@@ -756,6 +783,8 @@ export function useInlineWizard(): UseInlineWizardReturn {
existingDocs: undefined,
autoRunFolderPath: effectiveAutoRunFolderPath,
sessionSshRemoteConfig: currentState.sessionSshRemoteConfig,
+ conductorProfile: currentState.conductorProfile,
+ historyFilePath: currentState.historyFilePath,
});
conversationSessionsMap.current.set(tabId, session);
// Update mode to 'new' since we're proceeding with a new plan
@@ -928,6 +957,7 @@ export function useInlineWizard(): UseInlineWizardReturn {
(currentState.projectPath ? getAutoRunFolderPath(currentState.projectPath) : null);
if (currentState.agentType && effectiveAutoRunFolderPath) {
+ // Use historyFilePath from state (fetched during startWizard)
const session = startInlineWizardConversation({
mode: newMode,
agentType: currentState.agentType,
@@ -937,6 +967,8 @@ export function useInlineWizard(): UseInlineWizardReturn {
existingDocs: undefined, // Will be loaded separately if needed
autoRunFolderPath: effectiveAutoRunFolderPath,
sessionSshRemoteConfig: currentState.sessionSshRemoteConfig,
+ conductorProfile: currentState.conductorProfile,
+ historyFilePath: currentState.historyFilePath,
});
conversationSessionsMap.current.set(tabId, session);
@@ -1191,6 +1223,7 @@ export function useInlineWizard(): UseInlineWizardReturn {
autoRunFolderPath: effectiveAutoRunFolderPath,
sessionId: currentState.sessionId || undefined,
sessionSshRemoteConfig: currentState.sessionSshRemoteConfig,
+ conductorProfile: currentState.conductorProfile,
callbacks: {
onStart: () => {
console.log('[useInlineWizard] Document generation started');
diff --git a/src/renderer/services/inlineWizardConversation.ts b/src/renderer/services/inlineWizardConversation.ts
index 27c5513f..fb799036 100644
--- a/src/renderer/services/inlineWizardConversation.ts
+++ b/src/renderer/services/inlineWizardConversation.ts
@@ -96,6 +96,10 @@ export interface InlineWizardConversationConfig {
remoteId: string | null;
workingDirOverride?: string;
};
+ /** Conductor profile (user's About Me from settings) */
+ conductorProfile?: string;
+ /** History file path for task recall (optional, enables AI to recall recent work) */
+ historyFilePath?: string;
}
/**
@@ -213,6 +217,7 @@ export function generateInlineWizardPrompt(config: InlineWizardConversationConfi
}
// Build template context for remaining variables
+ // Include historyFilePath for {{AGENT_HISTORY_PATH}} task recall
const templateContext: TemplateContext = {
session: {
id: 'inline-wizard',
@@ -223,6 +228,8 @@ export function generateInlineWizardPrompt(config: InlineWizardConversationConfi
autoRunFolderPath: autoRunFolderPath,
},
autoRunFolder: autoRunFolderPath,
+ conductorProfile: config.conductorProfile,
+ historyFilePath: config.historyFilePath,
};
// Substitute any remaining template variables
diff --git a/src/renderer/services/inlineWizardDocumentGeneration.ts b/src/renderer/services/inlineWizardDocumentGeneration.ts
index d04f960a..53d7ac0a 100644
--- a/src/renderer/services/inlineWizardDocumentGeneration.ts
+++ b/src/renderer/services/inlineWizardDocumentGeneration.ts
@@ -134,6 +134,8 @@ export interface DocumentGenerationConfig {
remoteId: string | null;
workingDirOverride?: string;
};
+ /** Conductor profile (user's About Me from settings) */
+ conductorProfile?: string;
/** Optional callbacks */
callbacks?: DocumentGenerationCallbacks;
}
@@ -358,6 +360,7 @@ export function generateDocumentPrompt(
cwd: directoryPath,
fullPath: directoryPath,
},
+ conductorProfile: config.conductorProfile,
};
// Substitute any remaining template variables
diff --git a/src/shared/templateVariables.ts b/src/shared/templateVariables.ts
index 04e9695a..2418d56d 100644
--- a/src/shared/templateVariables.ts
+++ b/src/shared/templateVariables.ts
@@ -3,6 +3,9 @@
*
* Available variables (case-insensitive):
*
+ * Conductor Variables (the Maestro user):
+ * {{CONDUCTOR_PROFILE}} - User's About Me profile (from Settings → General)
+ *
* Agent Variables:
* {{AGENT_NAME}} - Agent name
* {{AGENT_PATH}} - Agent home directory path (full path to project)
@@ -68,12 +71,15 @@ export interface TemplateContext {
documentPath?: string;
// History file path for task recall
historyFilePath?: string;
+ // Conductor profile (user's About Me from settings)
+ conductorProfile?: string;
}
// List of all available template variables for documentation (alphabetically sorted)
// Variables marked as autoRunOnly are only shown in Auto Run contexts, not in AI Commands settings
export const TEMPLATE_VARIABLES = [
{ variable: '{{AGENT_GROUP}}', description: 'Agent group name' },
+ { variable: '{{CONDUCTOR_PROFILE}}', description: 'Conductor\'s About Me profile' },
{ variable: '{{AGENT_HISTORY_PATH}}', description: 'History file path (task recall)' },
{ variable: '{{AGENT_NAME}}', description: 'Agent name' },
{ variable: '{{AGENT_PATH}}', description: 'Agent home directory path' },
@@ -120,11 +126,15 @@ export function substituteTemplateVariables(template: string, context: TemplateC
documentName,
documentPath,
historyFilePath,
+ conductorProfile,
} = context;
const now = new Date();
// Build replacements map
const replacements: Record = {
+ // Conductor variables (the Maestro user)
+ CONDUCTOR_PROFILE: conductorProfile || '',
+
// Agent variables
AGENT_NAME: session.name,
AGENT_PATH: session.fullPath || session.projectRoot || session.cwd,