address comments by bot

This commit is contained in:
A.K.M. Adib
2026-01-27 12:36:27 -05:00
parent 322b866a5a
commit f5bf268117
12 changed files with 413 additions and 109 deletions
+1 -1
View File
@@ -219,7 +219,7 @@ import {
import { McpClientManager } from '../tools/mcp-client-manager.js';
import type { EnvironmentSanitizationConfig } from '../services/environmentSanitization.js';
import { getErrorMessage } from '../utils/errors.js';
import { WriteTodosTool } from 'src/tools/write-todos.js';
import { WriteTodosTool } from '../tools/write-todos.js';
export type { FileFilteringOptions };
export {
+2 -2
View File
@@ -162,7 +162,7 @@ ${planModeToolsList}
- Save your plans as Markdown (.md) files directly to: \`${plansDir}/\`
- Use descriptive filenames: \`feature-name.md\` or \`bugfix-description.md\`
- **Source of Truth:** The UI is based on these markdown files. To show progress in the CLI, you MUST update the plan file with the status markers below.
- **Task Status Markers:** Use the following markers in your task lists to update the UI:
- **Task Status Markers:** Use the following markers in your task lists to update the UI (note that these are case-sensitive):
- \`- [ ] Task\` : Pending
- \`- [/] Task\` : In Progress
- \`- [x] Task\` : Completed
@@ -280,7 +280,7 @@ When requested to perform tasks like fixing bugs, adding features, refactoring,
**Monitoring Progress:**
- **Plans Directory:** \`${config.storage.getProjectTempPlansDir()}/\`
- If a plan file exists in this directory, you MUST update it to reflect your progress using the \`write_file\` or \`replace\` tools.
- Use markers: \`- [ ]\` (Pending), \`- [/]\` (In Progress), \`- [x]\` (Completed), \`- [-]\` (Cancelled).
- Use markers (case-sensitive): \`- [ ]\` (Pending), \`- [/]\` (In Progress), \`- [x]\` (Completed), \`- [-]\` (Cancelled).
## New Applications
+1
View File
@@ -97,6 +97,7 @@ export * from './utils/secure-browser-launcher.js';
export * from './utils/apiConversionUtils.js';
export * from './utils/channel.js';
export * from './utils/constants.js';
export * from './utils/security.js';
// Export services
export * from './services/fileDiscoveryService.js';
+12
View File
@@ -57,4 +57,16 @@ describe('parseMarkdownTodos', () => {
const todos = parseMarkdownTodos(markdown);
expect(todos).toEqual([{ description: 'A task', status: 'pending' }]);
});
it('is case-sensitive for completed marker', () => {
const markdown = `
- [x] lowercase
- [X] uppercase
`;
const todos = parseMarkdownTodos(markdown);
expect(todos).toEqual([
{ description: 'lowercase', status: 'completed' },
{ description: 'uppercase', status: 'pending' },
]);
});
});
+2 -2
View File
@@ -40,7 +40,7 @@ export function parseMarkdownTodos(content: string): Todo[] {
);
if (taskMarkerMatch) {
const marker = taskMarkerMatch[1].toLowerCase();
const marker = taskMarkerMatch[1];
const description = taskMarkerMatch[2].split('\n')[0].trim(); // Take only the first line as description
let status: TodoStatus = 'pending';
@@ -50,7 +50,7 @@ export function parseMarkdownTodos(content: string): Todo[] {
status = 'in_progress';
} else if (marker === '-') {
status = 'cancelled';
} else if (marker === '') {
} else if (marker === '' || marker === ' ') {
status = 'pending';
}
+100 -49
View File
@@ -14,81 +14,132 @@ export interface SecurityCheckResult {
reason?: string;
}
export interface SecurityCheckOptions {
/**
* The expected owner of the directory.
* - 'root': Owned by root (uid 0) on POSIX.
* - 'user': Owned by the current user.
* Defaults to 'root'.
*/
owner?: 'root' | 'user';
/**
* Whether to allow symbolic links.
* Defaults to false.
*/
allowSymlinks?: boolean;
}
/**
* Verifies if a directory is secure (owned by root and not writable by others).
* Verifies if a directory is secure.
*
* For 'root' owner (default):
* - POSIX: Owned by root (uid 0) and not writable by group or others.
* - Windows: ACLs checked to ensure standard users/groups don't have write access.
*
* For 'user' owner:
* - POSIX: Owned by current user and has restrictive permissions (0700).
* - Windows: Verified as a directory and not a symbolic link.
*
* @param dirPath The path to the directory to check.
* @param options Security check options.
* @returns A promise that resolves to a SecurityCheckResult.
*/
export async function isDirectorySecure(
dirPath: string,
options: SecurityCheckOptions = {},
): Promise<SecurityCheckResult> {
const { owner = 'root', allowSymlinks = false } = options;
try {
const stats = await fs.stat(dirPath);
const stats = await fs.lstat(dirPath);
if (!allowSymlinks && stats.isSymbolicLink()) {
return { secure: false, reason: 'Directory is a symbolic link' };
}
if (!stats.isDirectory()) {
return { secure: false, reason: 'Not a directory' };
}
if (os.platform() === 'win32') {
try {
// Check ACLs using PowerShell to ensure standard users don't have write access
const escapedPath = dirPath.replace(/'/g, "''");
const script = `
$path = '${escapedPath}';
$acl = Get-Acl -LiteralPath $path;
$rules = $acl.Access | Where-Object {
$_.AccessControlType -eq 'Allow' -and
(($_.FileSystemRights -match 'Write') -or ($_.FileSystemRights -match 'Modify') -or ($_.FileSystemRights -match 'FullControl'))
};
$insecureIdentity = $rules | Where-Object {
$_.IdentityReference.Value -match 'Users' -or $_.IdentityReference.Value -eq 'Everyone'
} | Select-Object -ExpandProperty IdentityReference;
Write-Output ($insecureIdentity -join ', ');
`;
if (owner === 'root') {
try {
// Check ACLs using PowerShell to ensure standard users don't have write access
const escapedPath = dirPath.replace(/'/g, "''");
const script = `
$path = '${escapedPath}';
$acl = Get-Acl -LiteralPath $path;
$rules = $acl.Access | Where-Object {
$_.AccessControlType -eq 'Allow' -and
(($_.FileSystemRights -match 'Write') -or ($_.FileSystemRights -match 'Modify') -or ($_.FileSystemRights -match 'FullControl'))
};
$insecureIdentity = $rules | Where-Object {
$_.IdentityReference.Value -match 'Users' -or $_.IdentityReference.Value -eq 'Everyone'
} | Select-Object -ExpandProperty IdentityReference;
Write-Output ($insecureIdentity -join ', ');
`;
const { stdout } = await spawnAsync('powershell', [
'-NoProfile',
'-NonInteractive',
'-Command',
script,
]);
const { stdout } = await spawnAsync('powershell', [
'-NoProfile',
'-NonInteractive',
'-Command',
script,
]);
const insecureGroups = stdout.trim();
if (insecureGroups) {
const insecureGroups = stdout.trim();
if (insecureGroups) {
return {
secure: false,
reason: `Directory '${dirPath}' is insecure. The following user groups have write permissions: ${insecureGroups}. To fix this, remove Write and Modify permissions for these groups from the directory's ACLs.`,
};
}
} catch (error) {
return {
secure: false,
reason: `Directory '${dirPath}' is insecure. The following user groups have write permissions: ${insecureGroups}. To fix this, remove Write and Modify permissions for these groups from the directory's ACLs.`,
reason: `A security check for the system policy directory '${dirPath}' failed and could not be completed. Please file a bug report. Original error: ${(error as Error).message}`,
};
}
return { secure: true };
} catch (error) {
return {
secure: false,
reason: `A security check for the system policy directory '${dirPath}' failed and could not be completed. Please file a bug report. Original error: ${(error as Error).message}`,
};
}
return { secure: true };
}
// POSIX checks
// Check ownership: must be root (uid 0)
if (stats.uid !== 0) {
return {
secure: false,
reason: `Directory '${dirPath}' is not owned by root (uid 0). Current uid: ${stats.uid}. To fix this, run: sudo chown root:root "${dirPath}"`,
};
}
if (owner === 'root') {
// Check ownership: must be root (uid 0)
if (stats.uid !== 0) {
return {
secure: false,
reason: `Directory '${dirPath}' is not owned by root (uid 0). Current uid: ${stats.uid}. To fix this, run: sudo chown root:root "${dirPath}"`,
};
}
// Check permissions: not writable by group (S_IWGRP) or others (S_IWOTH)
const mode = stats.mode;
if ((mode & (constants.S_IWGRP | constants.S_IWOTH)) !== 0) {
return {
secure: false,
reason: `Directory '${dirPath}' is writable by group or others (mode: ${mode.toString(
8,
)}). To fix this, run: sudo chmod g-w,o-w "${dirPath}"`,
};
// Check permissions: not writable by group (S_IWGRP) or others (S_IWOTH)
const mode = stats.mode;
if ((mode & (constants.S_IWGRP | constants.S_IWOTH)) !== 0) {
return {
secure: false,
reason: `Directory '${dirPath}' is writable by group or others (mode: ${mode.toString(
8,
)}). To fix this, run: sudo chmod g-w,o-w "${dirPath}"`,
};
}
} else {
const userInfo = os.userInfo();
if (stats.uid !== userInfo.uid) {
return {
secure: false,
reason: `Directory is not owned by the current user (uid ${userInfo.uid})`,
};
}
// Check for restrictive permissions (0700)
const mode = stats.mode & 0o777;
if (mode !== 0o700) {
return {
secure: false,
reason: `Directory has insecure permissions: ${mode.toString(8)} (expected 0700)`,
};
}
}
return { secure: true };