@@ -186,6 +186,84 @@ export class ShellService extends TypedEventEmitter<ShellEvents> {
186186 return session ;
187187 }
188188
189+ async createCommandSession ( options : {
190+ sessionId : string ;
191+ command : string ;
192+ cwd : string ;
193+ taskId ?: string ;
194+ } ) : Promise < void > {
195+ const { sessionId, command, cwd, taskId } = options ;
196+
197+ const existing = this . sessions . get ( sessionId ) ;
198+ if ( existing ) {
199+ return ;
200+ }
201+
202+ const taskEnv = await this . getTaskEnv ( taskId ) ;
203+ const workingDir = this . resolveWorkingDir ( sessionId , cwd ) ;
204+ const shell = getDefaultShell ( ) ;
205+
206+ log . info (
207+ `Creating command session ${ sessionId } : shell=${ shell } -c ..., cwd=${ workingDir } ` ,
208+ ) ;
209+
210+ const ptyProcess = pty . spawn ( shell , [ "-c" , command ] , {
211+ name : "xterm-256color" ,
212+ cols : 80 ,
213+ rows : 24 ,
214+ cwd : workingDir ,
215+ env : buildShellEnv ( taskEnv ) ,
216+ encoding : null ,
217+ } ) ;
218+
219+ this . processTracking . register (
220+ ptyProcess . pid ,
221+ "shell" ,
222+ `shell:${ sessionId } ` ,
223+ { sessionId, cwd : workingDir , command } ,
224+ taskId ,
225+ ) ;
226+
227+ let resolveExit : ( result : { exitCode : number } ) => void ;
228+ const exitPromise = new Promise < { exitCode : number } > ( ( resolve ) => {
229+ resolveExit = resolve ;
230+ } ) ;
231+
232+ const disposables : pty . IDisposable [ ] = [ ] ;
233+
234+ disposables . push (
235+ ptyProcess . onData ( ( data : string ) => {
236+ this . emit ( ShellEvent . Data , { sessionId, data } ) ;
237+ } ) ,
238+ ) ;
239+
240+ disposables . push (
241+ ptyProcess . onExit ( ( { exitCode } ) => {
242+ log . info ( `Command session ${ sessionId } exited with code ${ exitCode } ` ) ;
243+ this . processTracking . unregister ( ptyProcess . pid , "exited" ) ;
244+ const session = this . sessions . get ( sessionId ) ;
245+ if ( session ) {
246+ for ( const d of session . disposables ) {
247+ d . dispose ( ) ;
248+ }
249+ session . pty . destroy ( ) ;
250+ this . sessions . delete ( sessionId ) ;
251+ }
252+ this . emit ( ShellEvent . Exit , { sessionId, exitCode } ) ;
253+ resolveExit ( { exitCode } ) ;
254+ } ) ,
255+ ) ;
256+
257+ const session : ShellSession = {
258+ pty : ptyProcess ,
259+ exitPromise,
260+ command,
261+ disposables,
262+ } ;
263+
264+ this . sessions . set ( sessionId , session ) ;
265+ }
266+
189267 write ( sessionId : string , data : string ) : void {
190268 this . getSessionOrThrow ( sessionId ) . pty . write ( data ) ;
191269 }
0 commit comments