diff --git a/apps/studio/src/lib/editor/engine/chat/context.ts b/apps/studio/src/lib/editor/engine/chat/context.ts index 8a755ae43..9be3acea4 100644 --- a/apps/studio/src/lib/editor/engine/chat/context.ts +++ b/apps/studio/src/lib/editor/engine/chat/context.ts @@ -7,6 +7,7 @@ import { type HighlightMessageContext, type ImageMessageContext, type ProjectMessageContext, + type TerminalMessageContext, } from '@onlook/models/chat'; import type { DomElement } from '@onlook/models/element'; import type { ParsedError } from '@onlook/utility'; @@ -44,7 +45,14 @@ export class ChatContext { const fileContext = await this.getFileContext(fileNames); const imageContext = await this.getImageContext(); const projectContext = await this.getProjectContext(); - const context = [...fileContext, ...highlightedContext, ...imageContext, ...projectContext]; + const terminalContext = await this.getTerminalContext(); + const context = [ + ...fileContext, + ...highlightedContext, + ...imageContext, + ...projectContext, + ...terminalContext, + ]; return context; } @@ -72,6 +80,13 @@ export class ChatContext { return fileContext; } + private async getTerminalContext(): Promise { + const terminalContext = this.context.filter( + (context) => context.type === MessageContextType.TERMINAL, + ); + return terminalContext; + } + private async getHighlightedContext( selected: DomElement[], fileNames: Set, @@ -111,6 +126,26 @@ export class ChatContext { this.context = []; } + async addTerminalContext() { + const terminalContent = await this.getTerminalContent(); + if (terminalContent) { + this.context = this.context.filter((ctx) => ctx.type !== MessageContextType.TERMINAL); + this.context.push(terminalContent); + } + } + + async getTerminalContent(): Promise { + const output = await this.editorEngine.getTerminalOutput(); + if (!output) { + return null; + } + return { + type: MessageContextType.TERMINAL, + content: output, + displayName: 'Terminal', + }; + } + async addScreenshotContext() { const screenshot = await this.getScreenshotContext(); if (screenshot) { diff --git a/apps/studio/src/lib/editor/engine/index.ts b/apps/studio/src/lib/editor/engine/index.ts index 617d06822..6dfa70cfc 100644 --- a/apps/studio/src/lib/editor/engine/index.ts +++ b/apps/studio/src/lib/editor/engine/index.ts @@ -350,6 +350,18 @@ export class EditorEngine { }; } + async getTerminalOutput(): Promise { + try { + if (!this.projectsManager.runner) { + return null; + } + const history = await this.projectsManager.runner.getHistory(); + return history || null; + } catch (error) { + console.error('Failed to get terminal output:', error); + return null; + } + } canDeleteWindow() { return this.canvas.frames.length > 1; } diff --git a/apps/studio/src/routes/editor/EditPanel/ChatTab/ChatInput.tsx b/apps/studio/src/routes/editor/EditPanel/ChatTab/ChatInput.tsx index 7b632be68..5645d4dae 100644 --- a/apps/studio/src/routes/editor/EditPanel/ChatTab/ChatInput.tsx +++ b/apps/studio/src/routes/editor/EditPanel/ChatTab/ChatInput.tsx @@ -420,6 +420,33 @@ export const ChatInput = observer(() => { + + + + + + + {disabled ? 'Select an element to start' : 'Add terminal output'} + + +