@@ -654,10 +654,7 @@ export class PlutoNotebookController {
654654 `[CellOrderSync] Applying remote structure: ${ currentOrder . length } -> ${ plutoOrder . length } cells`
655655 ) ;
656656
657- this . remoteEditDepth . set (
658- notebookPath ,
659- ( this . remoteEditDepth . get ( notebookPath ) ?? 0 ) + 1
660- ) ;
657+ this . beginRemoteEdit ( notebookPath ) ;
661658 try {
662659 const edit = new vscode . WorkspaceEdit ( ) ;
663660 edit . set ( notebook . uri , [
@@ -668,16 +665,71 @@ export class PlutoNotebookController {
668665 ] ) ;
669666 await vscode . workspace . applyEdit ( edit ) ;
670667 } finally {
671- // Change events may be delivered after applyEdit resolves — release
672- // the suppression on the next tick
673- setTimeout ( ( ) => {
674- const depth = this . remoteEditDepth . get ( notebookPath ) ?? 1 ;
675- if ( depth <= 1 ) {
676- this . remoteEditDepth . delete ( notebookPath ) ;
677- } else {
678- this . remoteEditDepth . set ( notebookPath , depth - 1 ) ;
679- }
680- } , 0 ) ;
668+ this . endRemoteEditSoon ( notebookPath ) ;
669+ }
670+ }
671+
672+ private beginRemoteEdit ( notebookPath : string ) : void {
673+ this . remoteEditDepth . set (
674+ notebookPath ,
675+ ( this . remoteEditDepth . get ( notebookPath ) ?? 0 ) + 1
676+ ) ;
677+ }
678+
679+ /**
680+ * Releases remote-edit suppression on the next tick — change events may
681+ * be delivered after applyEdit resolves.
682+ */
683+ private endRemoteEditSoon ( notebookPath : string ) : void {
684+ setTimeout ( ( ) => {
685+ const depth = this . remoteEditDepth . get ( notebookPath ) ?? 1 ;
686+ if ( depth <= 1 ) {
687+ this . remoteEditDepth . delete ( notebookPath ) ;
688+ } else {
689+ this . remoteEditDepth . set ( notebookPath , depth - 1 ) ;
690+ }
691+ } , 0 ) ;
692+ }
693+
694+ /**
695+ * Applies a Pluto-side code edit (browser UI, MCP update_cell) to the
696+ * matching VSCode cell's text. Our own executeCell pushes echo back as
697+ * the same patch — the text-equality check drops those.
698+ */
699+ private async _applyRemoteCodeEdit (
700+ notebook : vscode . NotebookDocument ,
701+ cellId : CellId ,
702+ rawCode : string
703+ ) : Promise < void > {
704+ const cell = this . getCellByPlutoId ( notebook , cellId ) ;
705+ if ( ! cell ) {
706+ return ;
707+ }
708+ let newText = rawCode ?? "" ;
709+ if ( cell . kind === vscode . NotebookCellKind . Markup ) {
710+ const markdown = extractMarkdownContent ( newText ) ;
711+ if ( isDefined ( markdown ) ) {
712+ newText = markdown ;
713+ }
714+ }
715+ if ( cell . document . getText ( ) === newText ) {
716+ return ;
717+ }
718+ const notebookPath = notebook . uri . fsPath ;
719+ this . beginRemoteEdit ( notebookPath ) ;
720+ try {
721+ const edit = new vscode . WorkspaceEdit ( ) ;
722+ edit . replace (
723+ cell . document . uri ,
724+ new vscode . Range ( 0 , 0 , cell . document . lineCount , 0 ) ,
725+ newText
726+ ) ;
727+ await vscode . workspace . applyEdit ( edit ) ;
728+ this . outputChannel . appendLine (
729+ `[CodeSync] Cell ${ cellId } code updated from Pluto`
730+ ) ;
731+ } finally {
732+ this . endRemoteEditSoon ( notebookPath ) ;
681733 }
682734 }
683735
@@ -776,16 +828,23 @@ export class PlutoNotebookController {
776828 ) ;
777829 break ;
778830 }
779- case "cell_input " : {
831+ case "cell_inputs " : {
780832 if ( rest [ 1 ] === "code" && patch . op === "replace" ) {
781- // TODO here we need to update the code for the cell
833+ void this . _applyRemoteCodeEdit (
834+ notebook ,
835+ rest [ 0 ] as CellId ,
836+ patch . value as string
837+ ) . catch ( ( error ) => {
838+ this . outputChannel . appendLine (
839+ `[CodeSync] Failed for ${ rest [ 0 ] } : ${
840+ error instanceof Error ? error . message : String ( error )
841+ } `
842+ ) ;
843+ } ) ;
782844 }
783-
784- this . outputChannel . appendLine (
785- `[UNHANDLED] cell_input ${ patch . path . join ( "." ) } action ${
786- patch . op
787- } `
788- ) ;
845+ // Other cell_inputs fields (cell_id, code_folded, metadata)
846+ // have no document representation to update; structural
847+ // add/remove is handled via cell_order sync
789848 break ;
790849 }
791850 case "cell_results" :
0 commit comments