@@ -329,7 +329,6 @@ function validateRequestData(data, isAiMode) {
329329 } = data ;
330330
331331 const actualAiInstruction = ai_instruction || aiInstruction ;
332-
333332 if ( ! encoded_location ) {
334333 return {
335334 isValid : false ,
@@ -437,7 +436,11 @@ function readFileFromEncodedLocation(encodedLocation) {
437436 const filePath = decode ( encodedFilePath ) ;
438437 console . log ( `\x1b[36mℹ Decoded file path: ${ filePath } \x1b[0m` ) ;
439438
439+ < << << << HEAD
440440 // Check if the path is already absolute, if so use it directly
441+ = === ===
442+ // If filePath is absolute, use it directly. Otherwise, join with cwd.
443+ >>> >>> > 379c72f (updating server)
441444 const targetFile = path.isAbsolute(filePath)
442445 ? filePath
443446 : path.join(process.cwd(), filePath);
@@ -538,30 +541,22 @@ async function getAiChanges({
538541 * @returns {Promise<Object> } Backend response
539542 */
540543async function getChanges ( {
541- oldHtml,
542- newHtml,
543- githubRepoName,
544- encodedLocation,
545- styleChanges,
546- textChanges,
544+ changes,
547545 fileContent,
546+ githubRepoName,
548547 authHeader,
549548} ) {
550549 console . log (
551- `\x1b[36mℹ Getting changes from backend for file encoded_location: ${ encodedLocation } \x1b[0m`
550+ `\x1b[36mℹ Getting ${ changes . length } changes from backend\x1b[0m`
552551 ) ;
553552
554553 return await callBackendApi (
555554 "POST" ,
556555 "code-sync/get-changes" ,
557556 {
558- old_html : oldHtml ,
559- new_html : newHtml ,
560- github_repo_name : githubRepoName ,
561- encoded_location : encodedLocation ,
562- style_changes : styleChanges ,
563- text_changes : textChanges ,
557+ changes : changes , // Sending a list of changes
564558 file_content : fileContent ,
559+ github_repo_name : githubRepoName ,
565560 } ,
566561 authHeader
567562 ) ;
@@ -697,106 +692,190 @@ function createApp() {
697692 // Visual editor API route for regular agent changes
698693 app . post ( "/visual-editor-api" , async ( request , reply ) => {
699694 try {
700- const data = request . body ;
701- const {
702- encoded_location,
703- old_html,
704- new_html,
705- github_repo_name,
706- image_data,
707- filename,
708- style_changes,
709- text_changes,
710- agent_mode,
711- } = data ;
712-
713- // Debug logging to see what's being received
714- console . log (
715- `\x1b[36mℹ Visual Editor API Request data: ${ JSON . stringify ( {
716- data,
717- } ) } \x1b[0m`
718- ) ;
695+ const { changes, github_repo_name } = request . body ;
719696
720- // Validate request data for regular mode
721- const validation = validateRequestData ( data , false ) ;
722- if ( ! validation . isValid ) {
697+ if ( ! Array . isArray ( changes ) ) {
723698 return reply . code ( 400 ) . send ( {
724- error : validation . error ,
725- ...validation . errorData ,
699+ error : "Invalid request format: 'changes' must be an array." ,
726700 } ) ;
727701 }
728702
729- try {
730- const authHeader = request . headers [ "authorization" ] ;
731-
732- // Read file content
733- const { filePath, targetFile, fileContent } =
734- readFileFromEncodedLocation ( encoded_location ) ;
735-
736- // Save image if present
737- await saveImageData ( image_data , filename ) ;
703+ console . log (
704+ `\x1b[36mℹ Visual Editor API Request: Received ${ changes . length } changes for repo ${ github_repo_name } \x1b[0m`
705+ ) ;
738706
739- const getChangeApi = agent_mode ? getAgentChanges : getChanges ;
707+ const changesByFile = new Map ( ) ;
708+ for ( const change of changes ) {
709+ try {
710+ if ( ! change . encoded_location ) {
711+ console . warn (
712+ `\x1b[33m⚠ Skipping change with missing encoded_location.\x1b[0m`
713+ ) ;
714+ continue ;
715+ }
716+ const encodedFilePath = change . encoded_location . split ( ":" ) [ 0 ] ;
717+ const targetFile = decode ( encodedFilePath ) ;
718+ if ( ! targetFile ) {
719+ console . warn (
720+ `\x1b[33m⚠ Skipping change with undecodable file from encoded_location: ${ change . encoded_location } .\x1b[0m`
721+ ) ;
722+ continue ;
723+ }
724+ if ( ! changesByFile . has ( targetFile ) ) {
725+ changesByFile . set ( targetFile , [ ] ) ;
726+ }
727+ changesByFile . get ( targetFile ) . push ( change ) ;
728+ } catch ( e ) {
729+ console . error (
730+ `\x1b[31m✖ Error decoding location: ${ change . encoded_location } \x1b[0m`
731+ ) ;
732+ }
733+ }
740734
741- // Get agent changes from backend
742- const backendResponse = await getChangeApi ( {
743- oldHtml : old_html ,
744- newHtml : new_html ,
745- githubRepoName : github_repo_name ,
746- encodedLocation : encoded_location ,
747- styleChanges : style_changes ,
748- textChanges : text_changes ,
749- fileContent,
750- authHeader,
751- } ) ;
735+ const processingPromises = [ ] ;
736+ const updatedFiles = new Set ( ) ;
737+ const authHeader = request . headers . authorization ;
752738
753- console . log ( `\x1b[36mℹ Received response from backend\x1b[0m` ) ;
739+ for ( const [ targetFile , fileChanges ] of changesByFile . entries ( ) ) {
740+ const filePromise = ( async ( ) => {
741+ try {
742+ console . log (
743+ `\x1b[36mℹ Processing ${ fileChanges . length } changes for file: ${ targetFile } \x1b[0m`
744+ ) ;
754745
755- console . log ( "backendResponse" , backendResponse ) ;
756- // Check if this is the new agent response format with modified_content
757- if ( backendResponse . modified_content ) {
758- // Handle full file replacement
759- const formattedCode = await applyFullFileReplacement (
760- backendResponse . modified_content ,
761- targetFile
762- ) ;
746+ const { fileContent } = readFileFromEncodedLocation (
747+ fileChanges [ 0 ] . encoded_location
748+ ) ;
749+ const originalFileContent = fileContent ;
750+
751+ // Process image uploads first
752+ for ( const change of fileChanges ) {
753+ if ( change . image_data && change . filename ) {
754+ await saveImageData ( change . image_data , change . filename ) ;
755+ }
756+ }
757+
758+ // Separate changes by type
759+ const regularChanges = fileChanges . filter (
760+ ( c ) => ! c . mode && ! c . agent_mode
761+ ) ;
763762
764- return reply . code ( 200 ) . send ( {
765- success : true ,
766- message :
767- backendResponse . message || `Applied agent changes to ${ filePath } ` ,
768- modified_content : formattedCode ,
769- } ) ;
770- } else if (
771- backendResponse . changes &&
772- Array . isArray ( backendResponse . changes )
773- ) {
774- // Handle incremental changes (fallback)
775- const formattedCode = await applyChangesAndFormat (
776- fileContent ,
777- backendResponse . changes ,
778- targetFile
779- ) ;
763+ let modifiedContent = originalFileContent ;
764+ let backendResponse ;
765+
766+ if ( regularChanges . length > 0 ) {
767+ // Handle regular changes if no agent changes
768+ backendResponse = await getChanges ( {
769+ changes : regularChanges ,
770+ fileContent : originalFileContent ,
771+ githubRepoName : github_repo_name ,
772+ authHeader,
773+ } ) ;
774+ }
775+
776+ if ( backendResponse && backendResponse . modified_content ) {
777+ modifiedContent = backendResponse . modified_content ;
778+ await applyFullFileReplacement ( modifiedContent , targetFile ) ;
779+ updatedFiles . add ( targetFile ) ;
780+ } else {
781+ console . log (
782+ `\x1b[36mℹ No content changes to apply for file: ${ targetFile } \x1b[0m`
783+ ) ;
784+ }
785+ } catch ( err ) {
786+ console . error (
787+ `\x1b[31m✖ Error processing changes for file ${ targetFile } : ${ err . message } \x1b[0m`
788+ ) ;
789+ throw new Error ( `Failed to process file: ${ targetFile } ` ) ;
790+ }
791+ } ) ( ) ;
792+ processingPromises . push ( filePromise ) ;
793+ }
780794
781- return reply . code ( 200 ) . send ( {
782- success : true ,
783- message : `Applied ${ backendResponse . changes . length } changes to ${ filePath } ` ,
784- } ) ;
785- } else {
795+ const results = await Promise . allSettled ( processingPromises ) ;
796+ console . log ( "results" , results ) ;
797+ results . forEach ( ( result ) => {
798+ if ( result . status === "rejected" ) {
786799 console . error (
787- `\x1b[31m✗ Invalid response format: ${ JSON . stringify (
788- backendResponse
789- ) } \x1b[0m`
800+ `\x1b[31m✖ A file processing promise was rejected: ${ result . reason } \x1b[0m`
790801 ) ;
791- throw new Error ( "Invalid response format from backend" ) ;
792802 }
793- } catch ( apiError ) {
794- console . error ( "Error applying changes:" , apiError ) ;
795- return reply . code ( 500 ) . send ( { error : apiError . message } ) ;
803+ } ) ;
804+
805+ if ( updatedFiles . size === 0 ) {
806+ return reply . code ( 200 ) . send ( {
807+ message : "No changes were applied." ,
808+ updatedFiles : [ ] ,
809+ } ) ;
796810 }
797- } catch ( parseError ) {
798- console . error ( "Error parsing request data:" , parseError ) ;
799- return reply . code ( 400 ) . send ( { error : "Invalid JSON" } ) ;
811+
812+ return reply . code ( 200 ) . send ( {
813+ message : `Changes applied successfully to ${
814+ updatedFiles . size
815+ } file(s).`,
816+ updatedFiles : Array . from ( updatedFiles ) ,
817+ } ) ;
818+ } catch ( err ) {
819+ console . error (
820+ `\x1b[31m✖ Fatal error in /visual-editor-api: ${ err . message } \x1b[0m`
821+ ) ;
822+ return reply . code ( 500 ) . send ( {
823+ error : "An internal server error occurred" ,
824+ details : err . message ,
825+ } ) ;
826+ }
827+ } ) ;
828+
829+ // Visual editor API route for agent changes
830+ app . post ( "/visual-editor-api-agent" , async ( request , reply ) => {
831+ try {
832+ const data = request . body ;
833+ const {
834+ encoded_location,
835+ github_repo_name,
836+ image_data,
837+ filename,
838+ old_html,
839+ new_html,
840+ style_changes,
841+ text_changes,
842+ } = data ;
843+ const authHeader = request . headers [ "authorization" ] ;
844+
845+ const { targetFile, fileContent } =
846+ readFileFromEncodedLocation ( encoded_location ) ;
847+
848+ await saveImageData ( image_data , filename ) ;
849+
850+ const backendResponse = await getAgentChanges ( {
851+ oldHtml : old_html ,
852+ newHtml : new_html ,
853+ githubRepoName : github_repo_name ,
854+ encodedLocation : encoded_location ,
855+ styleChanges : style_changes ,
856+ textChanges : text_changes ,
857+ fileContent,
858+ authHeader,
859+ } ) ;
860+
861+ if ( ! backendResponse . changes || ! Array . isArray ( backendResponse . changes ) ) {
862+ throw new Error ( "Invalid response format from backend" ) ;
863+ }
864+
865+ const formattedCode = await applyChangesAndFormat (
866+ fileContent ,
867+ backendResponse . changes ,
868+ targetFile
869+ ) ;
870+
871+ return reply . code ( 200 ) . send ( {
872+ success : true ,
873+ message : "Agent changes applied successfully." ,
874+ modified_content : formattedCode ,
875+ } ) ;
876+ } catch ( err ) {
877+ console . error ( `Error in /visual-editor-api-agent: ${ err . message } ` ) ;
878+ return reply . code ( 500 ) . send ( { error : err . message } ) ;
800879 }
801880 } ) ;
802881
0 commit comments