Skip to content

Commit cfcef54

Browse files
committed
refactor: enhance directory listing with separate file and directory results
1 parent b39c8c0 commit cfcef54

File tree

6 files changed

+85
-49
lines changed

6 files changed

+85
-49
lines changed

extension/secureflow/packages/secureflow-cli/Dockerfile

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,6 @@ ENV NODE_ENV=production
4848
ENV TARGETS_FILE=/app/tools/mgmt/targets.txt
4949
ENV MAX_PLUGINS=50
5050

51-
# Create volume mount points for results and targets file
52-
VOLUME ["/app/tools/mgmt/results", "/app/tools/mgmt/targets.txt"]
53-
5451
# Set default working directory for the script
5552
WORKDIR /app
5653

extension/secureflow/packages/secureflow-cli/docker-compose.yml

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,6 @@ services:
44
context: .
55
dockerfile: Dockerfile
66
container_name: secureflow-plugin-analyzer
7-
volumes:
8-
# Mount the targets.txt file (read-only)
9-
- ./tools/mgmt/targets.txt:/app/tools/mgmt/targets.txt:ro
10-
# Mount results directory for output (read-write)
11-
- ./results:/app/tools/mgmt/results:rw
12-
# Mount settings directory for API key configuration
13-
- secureflow-settings:/home/secureflow/.secureflow
147
environment:
158
- MAX_PLUGINS=50
169
- NODE_ENV=production

extension/secureflow/packages/secureflow-cli/lib/prompts/common/security-review-cli.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ You are a highly experienced security engineer conducting a thorough code review
6161
6. ALWAYS use tools to navigate through the code to understand the complete context of the vulnerability.
6262
- Even though the project structure is provided, use list files tool to navigate through the code to understand the complete context of the vulnerability.
6363
- Use file request tool to request for files if needed for complete analysis iteratively.
64+
- Always start with list files tool to navigate through the code to understand the complete context of the vulnerability.
6465

6566
Strictly don't report below category of vulnerabilities from Analysis:
6667
- Theoretical vulnerabilities without practical impact
Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,30 @@
11
------
2-
2. Tool: list files in directory (equivalent to 'ls' command)
3-
Description: This method helps to list files in a directory
2+
2. Tool: Directory Listing (List Files and Subdirectories)
3+
Description: Explore directory contents to discover files and subdirectories for security analysis
4+
Purpose: Use this tool to navigate the project structure and identify files that need security review
5+
46
Format:
5-
<list_file_request path="./relative/path/to/directory" reason="short reason for requesting this directory" />
7+
<list_file_request path="./relative/path/to/directory" reason="brief explanation of why you need to explore this directory" />
8+
9+
When to use this tool:
10+
- Start security analysis by exploring the project root directory first
11+
- Navigate into subdirectories to understand the project structure
12+
- Discover configuration files, source code files, and security-relevant directories
13+
- Find entry points, authentication modules, database connections, and API endpoints
14+
- Explore directories mentioned in build files or configuration
15+
16+
Best practices:
17+
1. Always start with the root directory (path="./") to get an overview
18+
2. Use relative paths from the project root (e.g., "./src", "./config", "./api")
19+
3. Explore directories systematically - start broad, then go deeper
20+
4. Focus on security-relevant directories like src/, config/, auth/, api/, admin/
21+
5. Limit to 3-5 directory requests per iteration to avoid overwhelming context
22+
6. Don't request the same directory multiple times
23+
7. Skip hidden directories (starting with .) unless they contain configuration files
24+
8. Prioritize directories that likely contain business logic and security controls
625

7-
Rules for file requests:
8-
1. Use relative paths from the project root
9-
2. Provide a short reason for each request
10-
3. Files outside project scope will be ignored
11-
4. Request only directory listed in 'Files in the project' section
12-
5. Limit to 5 directories per request
13-
6. Do not request same directory multiple times
14-
7. Skip directories that were not found previously
15-
8. Skip non-source directories
16-
9. Follow project structure strictly
26+
Example usage sequence:
27+
1. <list_file_request path="./" reason="Get project overview and identify main directories" />
28+
2. <list_file_request path="./src" reason="Explore source code structure" />
29+
3. <list_file_request path="./config" reason="Check configuration files for security settings" />
1730
----

extension/secureflow/packages/secureflow-cli/scanner/ai-security-analyzer.js

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -181,11 +181,24 @@ class AISecurityAnalyzer {
181181
if (result.status === 'success') {
182182
context += `\n=== DIRECTORY: ${result.path} ===\n`;
183183
context += `Reason: ${result.reason}\n`;
184-
context += `Files and directories found (${result.fileCount} items):\n`;
185-
result.files.forEach(file => {
186-
const icon = file.type === 'directory' ? '📁' : '📄';
187-
context += `${icon} ${file.name} (${file.type})\n`;
188-
});
184+
context += `Total items: ${result.totalCount} (${result.directoryCount} directories, ${result.fileCount} files)\n`;
185+
186+
// List directories first
187+
if (result.directories && result.directories.length > 0) {
188+
context += `\nDirectories:\n`;
189+
result.directories.forEach(dir => {
190+
context += `📁 ${dir.name} (path: ${dir.relativePath})\n`;
191+
});
192+
}
193+
194+
// Then list files
195+
if (result.files && result.files.length > 0) {
196+
context += `\nFiles:\n`;
197+
result.files.forEach(file => {
198+
context += `📄 ${file.name} (path: ${file.relativePath})\n`;
199+
});
200+
}
201+
189202
context += `=== END DIRECTORY: ${result.path} ===\n`;
190203
} else {
191204
context += `❌ Directory listing failed for ${result.path}: ${result.reason}\n`;
@@ -210,7 +223,7 @@ class AISecurityAnalyzer {
210223
context += `\n[DIRECTORY LISTING RESULTS]\n`;
211224
listResults.forEach(result => {
212225
if (result.status === 'success') {
213-
context += `✅ ${result.path}: Successfully listed (${result.fileCount} items)\n`;
226+
context += `✅ ${result.path}: Successfully listed (${result.totalCount} total items: ${result.directoryCount} directories, ${result.fileCount} files)\n`;
214227
} else {
215228
context += `❌ Directory listing failed for ${result.path}: ${result.reason}. Don't request it again\n`;
216229
}

extension/secureflow/packages/secureflow-cli/scanner/file-request-handler.js

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -241,15 +241,19 @@ class FileRequestHandler {
241241
}
242242

243243
// List directory contents
244-
const files = await this._listDirectoryContents(fullPath);
244+
const contents = await this._listDirectoryContents(fullPath);
245245

246246
return {
247247
status: 'success',
248248
path: requestedPath,
249249
fullPath,
250-
files,
250+
files: contents.files,
251+
directories: contents.directories,
252+
all: contents.all,
251253
reason,
252-
fileCount: files.length
254+
fileCount: contents.files.length,
255+
directoryCount: contents.directories.length,
256+
totalCount: contents.all.length
253257
};
254258

255259
} catch (error) {
@@ -263,48 +267,63 @@ class FileRequestHandler {
263267
}
264268

265269
/**
266-
* List directory contents with filtering
270+
* List directory contents with filtering, including both files and directories with full paths
267271
*/
268272
async _listDirectoryContents(dirPath) {
269273
const { readdir } = require('fs').promises;
270274

271275
try {
272276
const items = await readdir(dirPath, { withFileTypes: true });
273-
const files = [];
277+
const result = {
278+
files: [],
279+
directories: [],
280+
all: []
281+
};
274282

275283
for (const item of items) {
276-
// Skip hidden files and directories
277-
if (item.name.startsWith('.') && item.name !== '.env' && item.name !== '.gitignore') {
284+
// Skip hidden files and directories (except important config files)
285+
if (item.name.startsWith('.') &&
286+
item.name !== '.env' &&
287+
item.name !== '.gitignore' &&
288+
item.name !== '.config' &&
289+
item.name !== '.npmrc' &&
290+
item.name !== '.dockerignore') {
278291
continue;
279292
}
280293

281294
const itemPath = path.join(dirPath, item.name);
282295
const relativePath = path.relative(this.projectPath, itemPath);
296+
const fullPath = path.resolve(itemPath);
297+
298+
const itemInfo = {
299+
name: item.name,
300+
type: item.isDirectory() ? 'directory' : 'file',
301+
relativePath: relativePath.startsWith('.') ? relativePath : `./${relativePath}`,
302+
fullPath: fullPath
303+
};
283304

284305
if (item.isDirectory()) {
285-
files.push({
286-
name: item.name,
287-
type: 'directory',
288-
relativePath: relativePath
289-
});
306+
result.directories.push(itemInfo);
290307
} else if (item.isFile()) {
291-
files.push({
292-
name: item.name,
293-
type: 'file',
294-
relativePath: relativePath
295-
});
308+
result.files.push(itemInfo);
296309
}
310+
311+
result.all.push(itemInfo);
297312
}
298313

299314
// Sort by type (directories first) then by name
300-
files.sort((a, b) => {
315+
const sortFn = (a, b) => {
301316
if (a.type !== b.type) {
302317
return a.type === 'directory' ? -1 : 1;
303318
}
304319
return a.name.localeCompare(b.name);
305-
});
320+
};
321+
322+
result.files.sort(sortFn);
323+
result.directories.sort(sortFn);
324+
result.all.sort(sortFn);
306325

307-
return files;
326+
return result;
308327
} catch (error) {
309328
throw new Error(`Failed to read directory: ${error.message}`);
310329
}

0 commit comments

Comments
 (0)