55using System . Reflection ;
66using System . Threading ;
77using System . Threading . Tasks ;
8- using Kscript . CSharp . Parser . Core ;
8+ using KitX . Core . Contract . Workflow ;
99using Microsoft . CodeAnalysis ;
1010using Microsoft . CodeAnalysis . CSharp ;
1111using Microsoft . CodeAnalysis . CSharp . Syntax ;
1212using Microsoft . CodeAnalysis . CSharp . Scripting ;
1313using Microsoft . CodeAnalysis . Scripting ;
14- using KitX . Core . Contract . Workflow ;
1514using KitX . Core . Workflow ;
1615using Serilog ;
1716
@@ -40,6 +39,9 @@ public class BlockScriptExecutor : IBlockScriptExecutor
4039 private BlockScriptExecutionGlobals ? _globals ;
4140 private IPluginManager ? _pluginManager ;
4241
42+ // Workflow ID for disk persistence of compiled assemblies
43+ private string ? _workflowId ;
44+
4345 // Block-level precompilation
4446 private readonly BlockCompiler _blockCompiler = new ( ) ;
4547 private Dictionary < string , string > ? _blockCodeCache ;
@@ -80,6 +82,48 @@ public void SetPluginManager(IPluginManager? pluginManager)
8082 _pluginManager = pluginManager ;
8183 }
8284
85+ /// <summary>
86+ /// Sets the workflow ID for disk persistence of compiled assemblies.
87+ /// When set, compiled assemblies are saved to and loaded from disk
88+ /// to enable cross-session reuse.
89+ /// </summary>
90+ public void SetWorkflowId ( string ? workflowId )
91+ {
92+ _workflowId = workflowId ;
93+ }
94+
95+ /// <summary>
96+ /// Compiles a BlockScript and persists it to disk (without executing).
97+ /// Used for pre-compilation at workflow save time.
98+ /// </summary>
99+ /// <param name="script">The block script to compile.</param>
100+ /// <param name="workflowId">Workflow ID for disk persistence.</param>
101+ /// <returns>True if compilation and persistence succeeded.</returns>
102+ public bool CompileForPersistence ( BlockScript script , string workflowId )
103+ {
104+ try
105+ {
106+ var compiled = _assemblyCompiler . CompileScript ( script , workflowId ) ;
107+ return compiled != null ;
108+ }
109+ catch ( Exception ex )
110+ {
111+ Log . Warning ( ex , "[BlockScriptExecutor] CompileForPersistence failed for workflow {WfId}" , workflowId ) ;
112+ return false ;
113+ }
114+ }
115+
116+ /// <summary>
117+ /// Preloads all persisted compiled scripts for a workflow from disk
118+ /// into the in-memory cache.
119+ /// </summary>
120+ /// <param name="workflowId">Workflow ID to preload scripts for.</param>
121+ /// <returns>Number of scripts successfully loaded.</returns>
122+ public int PreloadFromDisk ( string workflowId )
123+ {
124+ return _assemblyCompiler . PreloadFromDisk ( workflowId ) ;
125+ }
126+
83127 /// <summary>
84128 /// Executes a block script
85129 /// </summary>
@@ -100,7 +144,7 @@ public async Task<BlockScriptExecutionResult> ExecuteAsync(
100144 // On failure, falls back to the existing CSharpScript execution path.
101145 try
102146 {
103- var compiled = _assemblyCompiler . CompileScript ( script ) ;
147+ var compiled = _assemblyCompiler . CompileScript ( script , _workflowId ) ;
104148 if ( compiled != null )
105149 {
106150 Log . Debug ( "[BlockScriptExecutor] Using assembly-compiled execution path" ) ;
0 commit comments