@@ -7,13 +7,116 @@ import EditorFile from "lib/editorFile";
77import TerminalComponent from "./terminal" ;
88import "@xterm/xterm/css/xterm.css" ;
99import toast from "components/toast" ;
10+ import helpers from "utils/helpers" ;
11+
12+ const TERMINAL_SESSION_STORAGE_KEY = "acodeTerminalSessions" ;
1013
1114class TerminalManager {
1215 constructor ( ) {
1316 this . terminals = new Map ( ) ;
1417 this . terminalCounter = 0 ;
1518 }
1619
20+ getPersistedSessions ( ) {
21+ try {
22+ const stored = helpers . parseJSON (
23+ localStorage . getItem ( TERMINAL_SESSION_STORAGE_KEY ) ,
24+ ) ;
25+ if ( ! Array . isArray ( stored ) ) return [ ] ;
26+ return stored
27+ . map ( ( entry ) => {
28+ if ( ! entry ) return null ;
29+ if ( typeof entry === "string" ) {
30+ return { pid : entry , name : `Terminal ${ entry } ` } ;
31+ }
32+ if ( typeof entry === "object" && entry . pid ) {
33+ const pid = String ( entry . pid ) ;
34+ return {
35+ pid,
36+ name : entry . name || `Terminal ${ pid } ` ,
37+ } ;
38+ }
39+ return null ;
40+ } )
41+ . filter ( Boolean ) ;
42+ } catch ( error ) {
43+ console . error ( "Failed to read persisted terminal sessions:" , error ) ;
44+ return [ ] ;
45+ }
46+ }
47+
48+ savePersistedSessions ( sessions ) {
49+ try {
50+ localStorage . setItem (
51+ TERMINAL_SESSION_STORAGE_KEY ,
52+ JSON . stringify ( sessions ) ,
53+ ) ;
54+ } catch ( error ) {
55+ console . error ( "Failed to persist terminal sessions:" , error ) ;
56+ }
57+ }
58+
59+ persistTerminalSession ( pid , name ) {
60+ if ( ! pid ) return ;
61+
62+ const pidStr = String ( pid ) ;
63+ const sessions = this . getPersistedSessions ( ) ;
64+ const existingIndex = sessions . findIndex (
65+ ( session ) => session . pid === pidStr ,
66+ ) ;
67+ const sessionData = {
68+ pid : pidStr ,
69+ name : name || `Terminal ${ pidStr } ` ,
70+ } ;
71+
72+ if ( existingIndex >= 0 ) {
73+ sessions [ existingIndex ] = {
74+ ...sessions [ existingIndex ] ,
75+ ...sessionData ,
76+ } ;
77+ } else {
78+ sessions . push ( sessionData ) ;
79+ }
80+
81+ this . savePersistedSessions ( sessions ) ;
82+ }
83+
84+ removePersistedSession ( pid ) {
85+ if ( ! pid ) return ;
86+
87+ const pidStr = String ( pid ) ;
88+ const sessions = this . getPersistedSessions ( ) ;
89+ const nextSessions = sessions . filter ( ( session ) => session . pid !== pidStr ) ;
90+
91+ if ( nextSessions . length !== sessions . length ) {
92+ this . savePersistedSessions ( nextSessions ) ;
93+ }
94+ }
95+
96+ async restorePersistedSessions ( ) {
97+ const sessions = this . getPersistedSessions ( ) ;
98+ if ( ! sessions . length ) return ;
99+
100+ for ( const session of sessions ) {
101+ if ( ! session ?. pid ) continue ;
102+ if ( this . terminals . has ( session . pid ) ) continue ;
103+
104+ try {
105+ await this . createServerTerminal ( {
106+ pid : session . pid ,
107+ name : session . name ,
108+ reconnecting : true ,
109+ } ) ;
110+ } catch ( error ) {
111+ console . error (
112+ `Failed to restore terminal session ${ session . pid } :` ,
113+ error ,
114+ ) ;
115+ this . removePersistedSession ( session . pid ) ;
116+ }
117+ }
118+ }
119+
17120 /**
18121 * Create a new terminal session
19122 * @param {object } options - Terminal options
@@ -71,7 +174,7 @@ class TerminalManager {
71174
72175 // Connect to session if in server mode
73176 if ( terminalComponent . serverMode ) {
74- await terminalComponent . connectToSession ( ) ;
177+ await terminalComponent . connectToSession ( options . pid ) ;
75178 } else {
76179 // For local mode, just write a welcome message
77180 terminalComponent . write (
@@ -98,6 +201,10 @@ class TerminalManager {
98201 } ;
99202
100203 this . terminals . set ( uniqueId , instance ) ;
204+
205+ if ( terminalComponent . serverMode && terminalComponent . pid ) {
206+ this . persistTerminalSession ( terminalComponent . pid , terminalName ) ;
207+ }
101208 resolve ( instance ) ;
102209 } catch ( error ) {
103210 console . error ( "Failed to initialize terminal:" , error ) ;
@@ -368,6 +475,10 @@ class TerminalManager {
368475 const formattedTitle = `Terminal ${ this . terminalCounter } - ${ title } ` ;
369476 terminalFile . filename = formattedTitle ;
370477
478+ if ( terminalComponent . serverMode && terminalComponent . pid ) {
479+ this . persistTerminalSession ( terminalComponent . pid , formattedTitle ) ;
480+ }
481+
371482 // Refresh the header subtitle if this terminal is active
372483 if (
373484 editorManager . activeFile &&
@@ -421,6 +532,10 @@ class TerminalManager {
421532 if ( ! terminal ) return ;
422533
423534 try {
535+ if ( terminal . component . serverMode && terminal . component . pid ) {
536+ this . removePersistedSession ( terminal . component . pid ) ;
537+ }
538+
424539 // Cleanup resize observer
425540 if ( terminal . file . _resizeObserver ) {
426541 terminal . file . _resizeObserver . disconnect ( ) ;
0 commit comments