@@ -49,7 +49,7 @@ const ORACLE_BASE_URL = "https://oracle.the-undesirables.com";
4949const ORACLE_SEARCH_ENDPOINT = `${ ORACLE_BASE_URL } /api/v1/search` ;
5050const ORACLE_MARKET_ENDPOINT = `${ ORACLE_BASE_URL } /api/v1/market` ;
5151const SCATTER_MINT_URL = "https://scatter.art/the-undesirables" ;
52- const PLUGIN_VERSION = "2.4.3 " ;
52+ const PLUGIN_VERSION = "2.4.4 " ;
5353const COLLECTION_TOTAL = 4444 ;
5454const MINTED_COUNT = 273 ;
5555
@@ -216,8 +216,10 @@ async function loadWorkspace(workspacePath: string): Promise<SoulWorkspace> {
216216 if ( fs . existsSync ( skillsDir ) ) {
217217 const files = await fs . promises . readdir ( skillsDir ) ;
218218 for ( const file of files . filter ( ( f ) => f . endsWith ( ".md" ) ) ) {
219+ // Validate each skill file through getSafePath to prevent symlink escape
220+ const skillPath = getSafePath ( skillsDir , file ) ;
219221 workspace . skills [ file . replace ( ".md" , "" ) ] = await fs . promises . readFile (
220- path . join ( skillsDir , file ) ,
222+ skillPath ,
221223 "utf-8"
222224 ) ;
223225 }
@@ -1026,7 +1028,7 @@ Archetype: ${workspace.meta.archetype || "Unknown"}
10261028Strategy: ${ workspace . meta . strategy || "Unknown" }
10271029Token ID: ${ workspace . meta . token_id || "?" }
10281030Mode: ${ isDemo ? "DEMO (community soul)" : "FULL (NFT holder)" }
1029- Skills loaded: ${ skillCount } ${ isDemo ? "/5 (demo)" : "/24 (full)" }
1031+ Skills loaded: ${ skillCount } ${ isDemo ? " (demo)" : " (full)" }
10301032Memory entries: ${ workspace . memory . split ( "\n" ) . filter ( ( l ) => l . trim ( ) ) . length }
10311033Predictions: ${ workspace . predictions . length }
10321034
0 commit comments