@@ -29,6 +29,7 @@ import PermissionNotificationBanner from "../permission-notification-banner"
2929import PermissionApprovalModal from "../permission-approval-modal"
3030import SessionView from "../session/session-view"
3131import MessageSection from "../message-section"
32+ import PromptAttachmentsBar from "../prompt-input/PromptAttachmentsBar"
3233import { formatTokenTotal } from "../../lib/formatters"
3334import ContextMeter from "../context-meter"
3435import { sseManager } from "../../lib/sse-manager"
@@ -50,7 +51,8 @@ import type { Attachment } from "../../types/attachment"
5051import { setAgentModelPreference , useConfig } from "../../stores/preferences"
5152import { showPromptDialog } from "../../stores/alerts"
5253import { openSessionPreview , sessionPreviews , showSessionChat , showSessionPreview } from "../../stores/session-previews"
53- import { createSession , getDefaultModel , providers , sendMessage , setActiveParentSession , updateSessionModel } from "../../stores/sessions"
54+ import { createSession , executeCustomCommand , getDefaultModel , providers , runShellCommand , sendMessage , setActiveParentSession , updateSessionModel } from "../../stores/sessions"
55+ import { getAttachments , removeAttachment } from "../../stores/attachments"
5456
5557import type { LayoutMode } from "./shell/types"
5658import {
@@ -123,6 +125,7 @@ const InstanceShell2: Component<InstanceShellProps> = (props) => {
123125 const [ draftAgent , setDraftAgent ] = createSignal ( "" )
124126 const [ draftModel , setDraftModel ] = createSignal ( { providerId : "" , modelId : "" } )
125127 const [ draftModelManuallySelected , setDraftModelManuallySelected ] = createSignal ( false )
128+ const [ draftPromptInputApi , setDraftPromptInputApi ] = createSignal < PromptInputApi | null > ( null )
126129
127130 // Worktree selector manages its own dialogs.
128131 const [ showSessionSearch , setShowSessionSearch ] = createSignal ( false )
@@ -805,7 +808,16 @@ const InstanceShell2: Component<InstanceShellProps> = (props) => {
805808 setDraftModelManuallySelected ( true )
806809 }
807810
808- async function handleFirstPromptSend ( prompt : string , attachments : Attachment [ ] ) {
811+ const draftAttachments = createMemo ( ( ) => getAttachments ( props . instance . id , NO_SESSION_DRAFT_SESSION_ID ) )
812+
813+ function registerDraftPromptInputApi ( api : PromptInputApi ) {
814+ setDraftPromptInputApi ( api )
815+ return ( ) => {
816+ setDraftPromptInputApi ( ( current ) => ( current === api ? null : current ) )
817+ }
818+ }
819+
820+ async function createAndActivateDraftSession ( ) {
809821 const agent = draftAgent ( )
810822 const model = draftModel ( )
811823 if ( agent && model . providerId && model . modelId ) {
@@ -816,9 +828,24 @@ const InstanceShell2: Component<InstanceShellProps> = (props) => {
816828 await updateSessionModel ( props . instance . id , session . id , model )
817829 }
818830 setActiveParentSession ( props . instance . id , session . id )
831+ return session
832+ }
833+
834+ async function handleFirstPromptSend ( prompt : string , attachments : Attachment [ ] ) {
835+ const session = await createAndActivateDraftSession ( )
819836 await sendMessage ( props . instance . id , session . id , prompt , attachments )
820837 }
821838
839+ async function handleFirstPromptCommand ( commandName : string , args : string ) {
840+ const session = await createAndActivateDraftSession ( )
841+ await executeCustomCommand ( props . instance . id , session . id , commandName , args )
842+ }
843+
844+ async function handleFirstPromptShell ( command : string ) {
845+ const session = await createAndActivateDraftSession ( )
846+ await runShellCommand ( props . instance . id , session . id , command )
847+ }
848+
822849 const sessionLayout = (
823850 < div
824851 class = "session-shell-panels flex flex-1 min-h-0 overflow-x-hidden"
@@ -1079,14 +1106,32 @@ const InstanceShell2: Component<InstanceShellProps> = (props) => {
10791106 forceCompactStatusLayout = { showEmbeddedSidebarToggle ( ) }
10801107 />
10811108
1109+ < Show when = { draftAttachments ( ) . length > 0 } >
1110+ < PromptAttachmentsBar
1111+ attachments = { draftAttachments ( ) }
1112+ onRemoveAttachment = { ( attachmentId ) => {
1113+ const api = draftPromptInputApi ( )
1114+ if ( api ) {
1115+ api . removeAttachment ( attachmentId )
1116+ return
1117+ }
1118+ removeAttachment ( props . instance . id , NO_SESSION_DRAFT_SESSION_ID , attachmentId )
1119+ } }
1120+ onExpandTextAttachment = { ( attachmentId ) => draftPromptInputApi ( ) ?. expandTextAttachment ( attachmentId ) }
1121+ />
1122+ </ Show >
1123+
10821124 < PromptInput
10831125 instanceId = { props . instance . id }
10841126 instanceFolder = { props . instance . folder }
10851127 sessionId = { NO_SESSION_DRAFT_SESSION_ID }
10861128 isActive = { props . isActiveInstance }
10871129 compactLayout = { compactPromptLayout ( ) }
10881130 onSend = { handleFirstPromptSend }
1131+ onCommand = { handleFirstPromptCommand }
1132+ onRunShell = { handleFirstPromptShell }
10891133 escapeInDebounce = { props . escapeInDebounce }
1134+ registerPromptInputApi = { registerDraftPromptInputApi }
10901135 />
10911136 </ div >
10921137 }
0 commit comments