feat(plan): add core logic and exit_plan_mode tool definition (#18110)

This commit is contained in:
Jerop Kipruto
2026-02-02 22:30:03 -05:00
committed by GitHub
parent 01e33465bd
commit ed26ea49e9
13 changed files with 981 additions and 2 deletions
+49
View File
@@ -228,6 +228,55 @@ export function isWithinRoot(
);
}
/**
* Safely resolves a path to its real path if it exists, otherwise returns the absolute resolved path.
*/
export function getRealPath(filePath: string): string {
try {
return fs.realpathSync(filePath);
} catch {
return path.resolve(filePath);
}
}
/**
* Checks if a file's content is empty or contains only whitespace.
* Efficiently checks file size first, and only samples the beginning of the file.
* Honors Unicode BOM encodings.
*/
export async function isEmpty(filePath: string): Promise<boolean> {
try {
const stats = await fsPromises.stat(filePath);
if (stats.size === 0) return true;
// Sample up to 1KB to check for non-whitespace content.
// If a file is larger than 1KB and contains only whitespace,
// it's an extreme edge case we can afford to read slightly more of if needed,
// but for most valid plans/files, this is sufficient.
const fd = await fsPromises.open(filePath, 'r');
try {
const { buffer } = await fd.read({
buffer: Buffer.alloc(Math.min(1024, stats.size)),
offset: 0,
length: Math.min(1024, stats.size),
position: 0,
});
const bom = detectBOM(buffer);
const content = bom
? buffer.subarray(bom.bomLength).toString('utf8')
: buffer.toString('utf8');
return content.trim().length === 0;
} finally {
await fd.close();
}
} catch {
// If file is unreadable, we treat it as empty/invalid for validation purposes
return true;
}
}
/**
* Heuristic: determine if a file is likely binary.
* Now BOM-aware: if a Unicode BOM is detected, we treat it as text.