@@ -17,6 +17,16 @@ import { FileListProcessor } from './fileListProcessor';
1717// Import the moved type
1818import type { SelectedFile } from '@promptcode/core' ;
1919
20+ // Security helper to prevent path traversal attacks
21+ function resolveSecurePath ( rootPath : string , relativePath : string ) : string {
22+ const resolved = path . resolve ( rootPath , relativePath ) ;
23+ const rootResolved = path . resolve ( rootPath ) + path . sep ;
24+ if ( ! resolved . startsWith ( rootResolved ) ) {
25+ throw new Error ( 'Security Error: Path traversal attempt detected' ) ;
26+ }
27+ return resolved ;
28+ }
29+
2030let lastGeneratedPrompt : string | null = null ; // Variable to store the last generated prompt
2131
2232// Export a getter for the last generated prompt
@@ -99,7 +109,7 @@ export function activate(context: vscode.ExtensionContext) {
99109
100110 // Initialize output channel
101111 const outputChannel = vscode . window . createOutputChannel ( 'PromptCode' ) ;
102- outputChannel . show ( true ) ;
112+ // Don't show automatically - only show on error or user request
103113
104114 // Get the workspace folder
105115 const workspaceRoot = vscode . workspace . workspaceFolders && vscode . workspace . workspaceFolders . length > 0
@@ -181,7 +191,7 @@ export function activate(context: vscode.ExtensionContext) {
181191 // Register select all command
182192 const selectAllCommand = vscode . commands . registerCommand ( 'promptcode.selectAll' , async ( ) => {
183193 await vscode . window . withProgress ( {
184- location : vscode . ProgressLocation . Notification ,
194+ location : vscode . ProgressLocation . Window ,
185195 title : "Selecting all files..." ,
186196 cancellable : false
187197 } , async ( ) => {
@@ -193,7 +203,7 @@ export function activate(context: vscode.ExtensionContext) {
193203 // Register deselect all command
194204 const deselectAllCommand = vscode . commands . registerCommand ( 'promptcode.deselectAll' , async ( ) => {
195205 await vscode . window . withProgress ( {
196- location : vscode . ProgressLocation . Notification ,
206+ location : vscode . ProgressLocation . Window ,
197207 title : "Deselecting all files..." ,
198208 cancellable : false
199209 } , async ( ) => {
@@ -236,7 +246,7 @@ export function activate(context: vscode.ExtensionContext) {
236246 const generatePromptCommand = vscode . commands . registerCommand ( 'promptcode.generatePrompt' , async ( ) => {
237247 // Generate the prompt text
238248 vscode . window . withProgress ( {
239- location : vscode . ProgressLocation . Notification ,
249+ location : vscode . ProgressLocation . Window ,
240250 title : 'Generating Prompt' ,
241251 cancellable : false
242252 } , async ( progress ) => {
@@ -353,7 +363,7 @@ export function activate(context: vscode.ExtensionContext) {
353363 const copyPromptDirectlyCommand = vscode . commands . registerCommand ( 'promptcode.copyPromptDirectly' , async ( ) => {
354364 // Generate the prompt text and copy to clipboard
355365 vscode . window . withProgress ( {
356- location : vscode . ProgressLocation . Notification ,
366+ location : vscode . ProgressLocation . Window ,
357367 title : 'Generating and Copying Prompt' ,
358368 cancellable : false
359369 } , async ( progress ) => {
@@ -440,7 +450,7 @@ export function activate(context: vscode.ExtensionContext) {
440450 }
441451
442452 // Construct the full file path using the determined workspace folder
443- const fullPath = path . join ( targetWorkspaceFolder . uri . fsPath , filePath ) ;
453+ const fullPath = resolveSecurePath ( targetWorkspaceFolder . uri . fsPath , filePath ) ;
444454
445455 // Handle different file operations
446456 switch ( fileOperation . toUpperCase ( ) ) {
@@ -457,6 +467,17 @@ export function activate(context: vscode.ExtensionContext) {
457467 break ;
458468
459469 case 'DELETE' :
470+ // Confirm deletion with user for security
471+ const userChoice = await vscode . window . showWarningMessage (
472+ `Are you sure you want to delete ${ path . basename ( fullPath ) } ?` ,
473+ { modal : true , detail : `Full path: ${ fullPath } ` } ,
474+ 'Delete' ,
475+ 'Cancel'
476+ ) ;
477+ if ( userChoice !== 'Delete' ) {
478+ vscode . window . showInformationMessage ( 'Deletion cancelled' ) ;
479+ return ;
480+ }
460481 // Delete the file
461482 await fs . promises . unlink ( fullPath ) ;
462483 break ;
@@ -687,7 +708,7 @@ export function activate(context: vscode.ExtensionContext) {
687708
688709 // Show progress indicator
689710 await vscode . window . withProgress ( {
690- location : vscode . ProgressLocation . Notification ,
711+ location : vscode . ProgressLocation . Window ,
691712 title : "Processing selected files..." ,
692713 cancellable : false
693714 } , async ( progress ) => {
@@ -1112,7 +1133,8 @@ export function activate(context: vscode.ExtensionContext) {
11121133 } else {
11131134 // It's a relative path, check if workspaceFolderRootPath is provided and valid
11141135 if ( workspaceFolderRootPath && fs . existsSync ( workspaceFolderRootPath ) ) {
1115- fileUri = vscode . Uri . file ( path . join ( workspaceFolderRootPath , filePath ) ) ;
1136+ const securePath = resolveSecurePath ( workspaceFolderRootPath , filePath ) ;
1137+ fileUri = vscode . Uri . file ( securePath ) ;
11161138 } else {
11171139 // Try to find the file in one of the workspace folders
11181140 let found = false ;
0 commit comments