mirror of
https://github.com/jlengrand/Maestro.git
synced 2026-03-10 08:31:19 +00:00
MAESTRO: Add FilePreviewTab type and unified tab system foundation
Phase 1 of file preview tabs feature: - Add FilePreviewTab interface with id, path, name, extension, scrollTop, searchQuery, editMode, editContent, and createdAt fields - Add UnifiedTabRef type for tab ordering across types - Add filePreviewTabs, activeFileTabId, and unifiedTabOrder to Session - Update all 13 session creation locations with new fields - Update session restoration to hydrate new fields from persistence This establishes the data model for coexisting AI tabs, file preview tabs, and future terminal tabs in a unified tab bar.
This commit is contained in:
@@ -1111,6 +1111,9 @@ function MaestroConsoleInner() {
|
||||
},
|
||||
],
|
||||
activeTabId: defaultTabId,
|
||||
filePreviewTabs: [],
|
||||
activeFileTabId: null,
|
||||
unifiedTabOrder: [{ type: 'ai' as const, id: defaultTabId }],
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1235,6 +1238,12 @@ function MaestroConsoleInner() {
|
||||
agentError: undefined,
|
||||
agentErrorPaused: false,
|
||||
closedTabHistory: [], // Runtime-only, reset on load
|
||||
// File preview tabs - initialize from persisted data or empty
|
||||
filePreviewTabs: correctedSession.filePreviewTabs || [],
|
||||
activeFileTabId: correctedSession.activeFileTabId ?? null,
|
||||
unifiedTabOrder:
|
||||
correctedSession.unifiedTabOrder ||
|
||||
resetAiTabs.map((tab) => ({ type: 'ai' as const, id: tab.id })),
|
||||
};
|
||||
} else {
|
||||
// Process spawn failed
|
||||
@@ -1652,6 +1661,9 @@ function MaestroConsoleInner() {
|
||||
aiTabs: [initialTab],
|
||||
activeTabId: initialTabId,
|
||||
closedTabHistory: [],
|
||||
filePreviewTabs: [],
|
||||
activeFileTabId: null,
|
||||
unifiedTabOrder: [{ type: 'ai' as const, id: initialTabId }],
|
||||
customPath: parentSession.customPath,
|
||||
customArgs: parentSession.customArgs,
|
||||
customEnvVars: parentSession.customEnvVars,
|
||||
@@ -7287,6 +7299,9 @@ You are taking over this conversation. Based on the context above, provide a bri
|
||||
aiTabs: [initialTab],
|
||||
activeTabId: initialTabId,
|
||||
closedTabHistory: [],
|
||||
filePreviewTabs: [],
|
||||
activeFileTabId: null,
|
||||
unifiedTabOrder: [{ type: 'ai' as const, id: initialTabId }],
|
||||
customPath: parentSession.customPath,
|
||||
customArgs: parentSession.customArgs,
|
||||
customEnvVars: parentSession.customEnvVars,
|
||||
@@ -7468,6 +7483,9 @@ You are taking over this conversation. Based on the context above, provide a bri
|
||||
aiTabs: [initialTab],
|
||||
activeTabId: initialTabId,
|
||||
closedTabHistory: [],
|
||||
filePreviewTabs: [],
|
||||
activeFileTabId: null,
|
||||
unifiedTabOrder: [{ type: 'ai' as const, id: initialTabId }],
|
||||
customPath: session.customPath,
|
||||
customArgs: session.customArgs,
|
||||
customEnvVars: session.customEnvVars,
|
||||
@@ -8756,6 +8774,10 @@ You are taking over this conversation. Based on the context above, provide a bri
|
||||
aiTabs: [initialTab],
|
||||
activeTabId: initialTabId,
|
||||
closedTabHistory: [],
|
||||
// File preview tabs - start empty, unified tab order starts with initial AI tab
|
||||
filePreviewTabs: [],
|
||||
activeFileTabId: null,
|
||||
unifiedTabOrder: [{ type: 'ai' as const, id: initialTabId }],
|
||||
// Nudge message - appended to every interactive user message
|
||||
nudgeMessage,
|
||||
// Per-agent config (path, args, env vars, model)
|
||||
@@ -8922,6 +8944,9 @@ You are taking over this conversation. Based on the context above, provide a bri
|
||||
aiTabs: [initialTab],
|
||||
activeTabId: initialTabId,
|
||||
closedTabHistory: [],
|
||||
filePreviewTabs: [],
|
||||
activeFileTabId: null,
|
||||
unifiedTabOrder: [{ type: 'ai' as const, id: initialTabId }],
|
||||
// Auto Run configuration from wizard
|
||||
autoRunFolderPath,
|
||||
autoRunSelectedFile,
|
||||
@@ -10958,6 +10983,9 @@ You are taking over this conversation. Based on the context above, provide a bri
|
||||
aiTabs: [initialTab],
|
||||
activeTabId: initialTabId,
|
||||
closedTabHistory: [],
|
||||
filePreviewTabs: [],
|
||||
activeFileTabId: null,
|
||||
unifiedTabOrder: [{ type: 'ai' as const, id: initialTabId }],
|
||||
customPath: activeSession.customPath,
|
||||
customArgs: activeSession.customArgs,
|
||||
customEnvVars: activeSession.customEnvVars,
|
||||
@@ -11133,6 +11161,9 @@ You are taking over this conversation. Based on the context above, provide a bri
|
||||
aiTabs: [initialTab],
|
||||
activeTabId: initialTabId,
|
||||
closedTabHistory: [],
|
||||
filePreviewTabs: [],
|
||||
activeFileTabId: null,
|
||||
unifiedTabOrder: [{ type: 'ai' as const, id: initialTabId }],
|
||||
customPath: activeSession.customPath,
|
||||
customArgs: activeSession.customArgs,
|
||||
customEnvVars: activeSession.customEnvVars,
|
||||
@@ -11282,6 +11313,9 @@ You are taking over this conversation. Based on the context above, provide a bri
|
||||
aiTabs: [initialTab],
|
||||
activeTabId: initialTabId,
|
||||
closedTabHistory: [],
|
||||
filePreviewTabs: [],
|
||||
activeFileTabId: null,
|
||||
unifiedTabOrder: [{ type: 'ai' as const, id: initialTabId }],
|
||||
customPath: createWorktreeSession.customPath,
|
||||
customArgs: createWorktreeSession.customArgs,
|
||||
customEnvVars: createWorktreeSession.customEnvVars,
|
||||
@@ -13215,6 +13249,9 @@ You are taking over this conversation. Based on the context above, provide a bri
|
||||
aiTabs: [initialTab],
|
||||
activeTabId: initialTabId,
|
||||
closedTabHistory: [],
|
||||
filePreviewTabs: [],
|
||||
activeFileTabId: null,
|
||||
unifiedTabOrder: [{ type: 'ai' as const, id: initialTabId }],
|
||||
// Custom agent config
|
||||
customPath: data.customPath,
|
||||
customArgs: data.customArgs,
|
||||
|
||||
@@ -442,6 +442,29 @@ export interface ClosedTab {
|
||||
closedAt: number; // Timestamp when closed
|
||||
}
|
||||
|
||||
/**
|
||||
* File Preview Tab for in-tab file viewing.
|
||||
* Designed to coexist with AITab and future terminal tabs in the unified tab system.
|
||||
* File tabs persist across session switches and app restarts.
|
||||
*/
|
||||
export interface FilePreviewTab {
|
||||
id: string; // Unique tab ID (UUID)
|
||||
path: string; // Full file path
|
||||
name: string; // Filename without extension (displayed as tab name)
|
||||
extension: string; // File extension with dot (e.g., '.md', '.ts') - shown as badge
|
||||
scrollTop: number; // Saved scroll position
|
||||
searchQuery: string; // Preserved search query
|
||||
editMode: boolean; // Whether tab was in edit mode
|
||||
editContent: string | undefined; // Unsaved edit content (undefined if no pending changes)
|
||||
createdAt: number; // Timestamp for ordering
|
||||
}
|
||||
|
||||
/**
|
||||
* Reference to any tab in the unified tab system.
|
||||
* Used for unified tab ordering across different tab types.
|
||||
*/
|
||||
export type UnifiedTabRef = { type: 'ai' | 'file'; id: string };
|
||||
|
||||
export interface Session {
|
||||
id: string;
|
||||
groupId?: string;
|
||||
@@ -559,6 +582,15 @@ export interface Session {
|
||||
activeTabId: string;
|
||||
// Stack of recently closed tabs for undo (max 25, runtime-only, not persisted)
|
||||
closedTabHistory: ClosedTab[];
|
||||
|
||||
// File Preview Tabs - in-tab file viewing (coexists with AI tabs and future terminal tabs)
|
||||
// Tabs are interspersed visually but stored separately for type safety
|
||||
filePreviewTabs: FilePreviewTab[];
|
||||
// Currently active file tab ID (null if an AI tab is active)
|
||||
activeFileTabId: string | null;
|
||||
// Unified tab ordering - determines visual order of all tabs (AI and file)
|
||||
unifiedTabOrder: UnifiedTabRef[];
|
||||
|
||||
// Saved scroll position for terminal/shell output view
|
||||
terminalScrollTop?: number;
|
||||
// Draft input for terminal mode (persisted across session switches)
|
||||
|
||||
@@ -893,6 +893,9 @@ export function createMergedSession(
|
||||
aiTabs: [mergedTab],
|
||||
activeTabId: tabId,
|
||||
closedTabHistory: [],
|
||||
filePreviewTabs: [],
|
||||
activeFileTabId: null,
|
||||
unifiedTabOrder: [{ type: 'ai' as const, id: tabId }],
|
||||
};
|
||||
|
||||
return { session, tabId };
|
||||
|
||||
Reference in New Issue
Block a user