Function bodies 337 total
sanitizeForComment function · javascript · L200-L207 (8 LOC)src/utils/helpers.js
function sanitizeForComment(str) {
if (!str) return '';
return str
.replace(/--/g, '—') // Replace double hyphen with em dash
.replace(/</g, '‹') // Replace angle brackets
.replace(/>/g, '›')
.trim();
}formatBytes function · javascript · L220-L230 (11 LOC)src/utils/helpers.js
function formatBytes(bytes, decimals = 2) {
if (bytes === 0) return '0 B';
const k = 1024;
const dm = decimals < 0 ? 0 : decimals;
const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}formatDuration function · javascript · L235-L249 (15 LOC)src/utils/helpers.js
function formatDuration(ms) {
if (ms < 1000) return `${ms}ms`;
const seconds = Math.floor(ms / 1000);
const minutes = Math.floor(seconds / 60);
const hours = Math.floor(minutes / 60);
if (hours > 0) {
return `${hours}h ${minutes % 60}m ${seconds % 60}s`;
} else if (minutes > 0) {
return `${minutes}m ${seconds % 60}s`;
} else {
return `${seconds}s`;
}
}parseSize function · javascript · L254-L272 (19 LOC)src/utils/helpers.js
function parseSize(sizeStr) {
const units = {
B: 1,
KB: 1024,
MB: 1024 * 1024,
GB: 1024 * 1024 * 1024,
TB: 1024 * 1024 * 1024 * 1024,
};
const match = sizeStr.toString().match(/^(\d+(?:\.\d+)?)\s*([KMGT]?B)?$/i);
if (!match) {
throw new Error(`Invalid size format: ${sizeStr}`);
}
const value = parseFloat(match[1]);
const unit = (match[2] || 'B').toUpperCase();
return Math.floor(value * (units[unit] || 1));
}chunk function · javascript · L277-L283 (7 LOC)src/utils/helpers.js
function chunk(array, size) {
const chunks = [];
for (let i = 0; i < array.length; i += size) {
chunks.push(array.slice(i, i + size));
}
return chunks;
}debounce function · javascript · L288-L300 (13 LOC)src/utils/helpers.js
function debounce(fn, delay) {
let timeoutId;
return function debounced(...args) {
clearTimeout(timeoutId);
return new Promise((resolve) => {
timeoutId = setTimeout(() => {
resolve(fn.apply(this, args));
}, delay);
});
};
}createCache function · javascript · L305-L340 (36 LOC)src/utils/helpers.js
function createCache(ttl = 3600000) {
const cache = new Map();
return {
get(key) {
const item = cache.get(key);
if (!item) return null;
if (Date.now() > item.expiry) {
cache.delete(key);
return null;
}
return item.value;
},
set(key, value) {
cache.set(key, {
value,
expiry: Date.now() + ttl,
});
},
delete(key) {
cache.delete(key);
},
clear() {
cache.clear();
},
size() {
return cache.size;
},
};
}Same scanner, your repo: https://repobility.com — Repobility
escapeXml function · javascript · L345-L355 (11 LOC)src/utils/helpers.js
function escapeXml(str) {
const xmlEscapes = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": ''',
};
return str.replace(/[&<>"']/g, (char) => xmlEscapes[char]);
}sanitizeForXml function · javascript · L374-L389 (16 LOC)src/utils/helpers.js
function sanitizeForXml(content) {
// Handle non-string input by converting to empty string
if (content === null || content === undefined || typeof content !== 'string') {
return '';
}
// Handle empty strings
if (!content) {
return '';
}
// Remove invalid XML control characters (0x00-0x1F except 0x09, 0x0A, 0x0D)
// Also remove 0x7F (DEL) which is technically invalid in XML 1.0
// eslint-disable-next-line no-control-regex
return content.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, '');
}readRules function · javascript · L46-L71 (26 LOC)src/utils/ignoreWalker.js
async function readRules(filePath, useCache = false) {
if (useCache) {
const cached = ruleCache.get(filePath);
if (cached) {
return cached;
}
}
try {
const content = await fs.readFile(filePath, 'utf8');
// Strip UTF-8 BOM if present
const cleaned = content.charCodeAt(0) === 0xfeff ? content.slice(1) : content;
const rules = cleaned.split('\n');
if (useCache) {
ruleCache.set(filePath, rules);
}
return rules;
} catch (error) {
// Only cache "file not found" — transient errors (EMFILE, EACCES) should not
// be cached because they may resolve on the next call.
if (useCache && error.code === 'ENOENT') {
ruleCache.set(filePath, []);
}
return [];
}
}isIgnored function · javascript · L81-L121 (41 LOC)src/utils/ignoreWalker.js
function isIgnored(absPath, root, layers, isDirectory = false) {
const relToRoot = toPosix(path.relative(root, absPath));
let ignored = false;
let matchedRule = null;
let matchedLayer = null;
for (const { base, ig } of layers) {
const relToLayer = toPosix(path.relative(base, absPath));
// Skip if path isn't under this layer's base
if (relToLayer.startsWith('..')) continue;
// Test with directory trailing slash if it's a directory
const testPath = isDirectory && !relToLayer.endsWith('/') ? relToLayer + '/' : relToLayer;
// Use .test() if available (returns {ignored, unignored}), otherwise fallback to .ignores()
const result = ig.test?.(testPath) ?? {
ignored: ig.ignores(testPath),
unignored: false,
};
if (result.ignored !== undefined) {
if (result.ignored) {
ignored = true;
matchedRule = 'exclude';
matchedLayer = base;
}
if (result.unignored) {
ignored = false;
matchewalkWithIgnore function · javascript · L141-L305 (165 LOC)src/utils/ignoreWalker.js
export async function* walkWithIgnore(root, options = {}) {
const {
ignoreFileName = '.copytreeignore',
includeDirectories = false,
followSymlinks = false,
explain = false,
initialLayers = [],
config = {},
cache = false,
maxDepth = undefined,
} = options;
// Extract retry configuration with defaults
const retryConfig = {
maxAttempts: config?.copytree?.fs?.retryAttempts ?? 3,
initialDelay: config?.copytree?.fs?.retryDelay ?? 100,
maxDelay: config?.copytree?.fs?.maxDelay ?? 2000,
};
const stats = {};
stats.filesScanned = 0;
stats.directoriesScanned = 0;
stats.directoriesPruned = 0;
stats.filesExcluded = 0;
async function* walk(dir, layers, depth = 0) {
stats.directoriesScanned++;
// Load ignore rules at this level
const ignoreFilePath = path.join(dir, ignoreFileName);
const localRules = await readRules(ignoreFilePath, cache);
const localIg = ignore().add(localRules);
const nextLayers = [...layerwalk function · javascript · L166-L302 (137 LOC)src/utils/ignoreWalker.js
async function* walk(dir, layers, depth = 0) {
stats.directoriesScanned++;
// Load ignore rules at this level
const ignoreFilePath = path.join(dir, ignoreFileName);
const localRules = await readRules(ignoreFilePath, cache);
const localIg = ignore().add(localRules);
const nextLayers = [...layers, { base: dir, ig: localIg }];
let entries;
try {
entries = await withFsRetry(() => fs.readdir(dir, { withFileTypes: true }), {
...retryConfig,
onRetry: ({ code }) => recordRetry(dir, code),
});
// Record success if there were retries
recordSuccessAfterRetry(dir);
} catch (error) {
// Record failure type based on error category
if (isRetryableFsError(error)) {
recordGiveUp(dir, error.code);
} else {
recordPermanent(dir, error.code);
}
// Can't read directory - skip it
return;
}
// Filter out ignore files themselves to prevent them from appearing in output
getAllFiles function · javascript · L313-L319 (7 LOC)src/utils/ignoreWalker.js
export async function getAllFiles(root, options = {}) {
const files = [];
for await (const file of walkWithIgnore(root, options)) {
files.push(file);
}
return files;
}testPath function · javascript · L331-L382 (52 LOC)src/utils/ignoreWalker.js
export async function testPath(testPath, root, options = {}) {
const { ignoreFileName = '.copytreeignore', config = {}, cache = false } = options;
// Build layers by walking up from root to the file's directory
const absPath = path.resolve(root, testPath);
const relPath = path.relative(root, absPath);
const dirPath = path.dirname(absPath);
const layers = [];
let currentDir = root;
// Walk down the directory tree, collecting ignore rules
const parts = relPath.split(path.sep);
for (let i = 0; i < parts.length; i++) {
const ignoreFilePath = path.join(currentDir, ignoreFileName);
const rules = await readRules(ignoreFilePath, cache);
if (rules.length > 0) {
const ig = ignore().add(rules);
layers.push({ base: currentDir, ig });
}
if (i < parts.length - 1) {
currentDir = path.join(currentDir, parts[i]);
}
}
// Determine if it's a directory
let isDirectory = false;
try {
// Use retry for stat in testPath with configCitation: Repobility (2026). State of AI-Generated Code. https://repobility.com/research/
Logger.constructor method · javascript · L31-L50 (20 LOC)src/utils/logger.js
constructor(options = {}) {
super();
this.options = {
// Structured logging options (new)
level: options.level, // lazy-loaded from config / env when undefined
format: options.format, // lazy-loaded from config / env when undefined
colorize: options.colorize, // lazy-loaded from config / env when undefined
timestamp: options.timestamp, // lazy-loaded from config when undefined
destination: options.destination, // lazy-loaded from config when undefined
// Legacy compatibility options
debug: options.debug, // will be lazy-loaded from config if not provided
silent: options.silent || false,
prefix: options.prefix || 'CopyTree',
useInkEvents: options.useInkEvents || false,
...options,
};
this.spinner = null;
}Logger._shouldLog method · javascript · L137-L146 (10 LOC)src/utils/logger.js
_shouldLog(level) {
const format = this._effectiveFormat;
if (format === 'silent') {
// Silent mode: only errors pass through
return level === 'error';
}
const messagePriority = LOG_LEVELS[level] ?? LOG_LEVELS.info;
const currentPriority = LOG_LEVELS[this._effectiveLevel] ?? LOG_LEVELS.info;
return messagePriority <= currentPriority;
}Logger._shouldColorize method · javascript · L149-L156 (8 LOC)src/utils/logger.js
_shouldColorize() {
if (this._effectiveFormat === 'json') return false;
const colorize = this._effectiveColorize;
if (colorize === 'always') return true;
if (colorize === 'never') return false;
// 'auto': colorize only when writing to a real TTY
return this._getOutputStream().isTTY === true;
}Logger._formatJsonLine method · javascript · L170-L202 (33 LOC)src/utils/logger.js
_formatJsonLine(level, message, ...args) {
let messageStr;
if (typeof message === 'string') {
messageStr = message;
} else {
try {
messageStr = JSON.stringify(message);
} catch {
messageStr = String(message);
}
}
const entry = { level, message: messageStr };
if (this._effectiveTimestamp) {
entry.timestamp = new Date().toISOString();
}
if (args.length > 0) {
entry.context = args.length === 1 ? args[0] : args;
}
try {
return JSON.stringify(entry);
} catch {
// Fallback for circular references, BigInt, or other non-serializable context
const safeEntry = { level, message: messageStr };
if (entry.timestamp) safeEntry.timestamp = entry.timestamp;
try {
return JSON.stringify(safeEntry);
} catch {
return `{"level":"${level}","message":"[unserializable]"}`;
}
}
}Logger._writeLog method · javascript · L214-L228 (15 LOC)src/utils/logger.js
_writeLog(level, coloredText, rawMessage, args = []) {
if (!this._shouldLog(level)) return;
const stream = this._getOutputStream();
const format = this._effectiveFormat;
if (format === 'json') {
stream.write(this._formatJsonLine(level, rawMessage, ...args) + '\n');
} else {
const text = this._shouldColorize()
? (coloredText ?? '')
: stripAnsi(typeof coloredText === 'string' ? coloredText : String(coloredText ?? ''));
stream.write(text + '\n');
}
}Logger.configure method · javascript · L243-L252 (10 LOC)src/utils/logger.js
configure(newOptions) {
if (newOptions.level !== undefined) this.options.level = newOptions.level;
if (newOptions.format !== undefined) this.options.format = newOptions.format;
if (newOptions.colorize !== undefined) this.options.colorize = newOptions.colorize;
if (newOptions.timestamp !== undefined) this.options.timestamp = newOptions.timestamp;
if (newOptions.destination !== undefined) this.options.destination = newOptions.destination;
// Legacy options
if (newOptions.silent !== undefined) this.options.silent = newOptions.silent;
if (newOptions.debug !== undefined) this.options.debug = newOptions.debug;
}Logger.info method · javascript · L259-L269 (11 LOC)src/utils/logger.js
info(message, ...args) {
if (this.options.useInkEvents) {
this.emit('log', {
type: 'info',
message: typeof message === 'string' ? message : JSON.stringify(message),
timestamp: Date.now(),
});
return;
}
this._writeLog('info', `${chalk.blue(`[${this.options.prefix}]`)} ${message}`, message, args);
}Logger.success method · javascript · L274-L284 (11 LOC)src/utils/logger.js
success(message, ...args) {
if (this.options.useInkEvents) {
this.emit('log', {
type: 'success',
message: typeof message === 'string' ? message : JSON.stringify(message),
timestamp: Date.now(),
});
return;
}
this._writeLog('success', chalk.green(`✓ ${message}`), message, args);
}Want fix-PRs on findings? Install Repobility's GitHub App · github.com/apps/repobility-bot
Logger.warn method · javascript · L289-L299 (11 LOC)src/utils/logger.js
warn(message, ...args) {
if (this.options.useInkEvents) {
this.emit('log', {
type: 'warning',
message: typeof message === 'string' ? message : JSON.stringify(message),
timestamp: Date.now(),
});
return;
}
this._writeLog('warn', chalk.yellow(`⚠ ${message}`), message, args);
}Logger.error method · javascript · L305-L315 (11 LOC)src/utils/logger.js
error(message, ...args) {
if (this.options.useInkEvents) {
this.emit('log', {
type: 'error',
message: typeof message === 'string' ? message : JSON.stringify(message),
timestamp: Date.now(),
});
return;
}
this._writeLog('error', chalk.red(`✗ ${message}`), message, args);
}Logger.logDebug method · javascript · L325-L335 (11 LOC)src/utils/logger.js
logDebug(message, ...args) {
if (this.options.useInkEvents) {
this.emit('log', {
type: 'debug',
message: typeof message === 'string' ? message : JSON.stringify(message),
timestamp: Date.now(),
});
return;
}
this._writeLog('debug', chalk.gray(`[DEBUG] ${message}`), message, args);
}Logger.startSpinner method · javascript · L343-L360 (18 LOC)src/utils/logger.js
startSpinner(message) {
if (this.options.useInkEvents) {
this.emit('progress', { type: 'start', message, timestamp: Date.now() });
return;
}
// Suppress spinner when format is json, silent, or when the stream is not a TTY
if (
this._effectiveFormat !== 'text' ||
!this._shouldLog('info') ||
!this._getOutputStream().isTTY
) {
return;
}
this.stopSpinner();
this.spinner = ora({ text: message, color: 'blue' }).start();
}Logger.updateSpinner method · javascript · L365-L374 (10 LOC)src/utils/logger.js
updateSpinner(message) {
if (this.options.useInkEvents) {
this.emit('progress', { type: 'update', message, timestamp: Date.now() });
return;
}
if (this.spinner && this._getOutputStream().isTTY) {
this.spinner.text = message;
}
}Logger.succeedSpinner method · javascript · L379-L389 (11 LOC)src/utils/logger.js
succeedSpinner(message) {
if (this.options.useInkEvents) {
this.emit('progress', { type: 'success', message, timestamp: Date.now() });
return;
}
if (this.spinner) {
this.spinner.succeed(message || this.spinner.text);
this.spinner = null;
}
}Logger.failSpinner method · javascript · L394-L404 (11 LOC)src/utils/logger.js
failSpinner(message) {
if (this.options.useInkEvents) {
this.emit('progress', { type: 'error', message, timestamp: Date.now() });
return;
}
if (this.spinner) {
this.spinner.fail(message || this.spinner.text);
this.spinner = null;
}
}Logger.stopSpinner method · javascript · L409-L423 (15 LOC)src/utils/logger.js
stopSpinner() {
if (this.options.useInkEvents) {
this.emit('progress', { type: 'stop', timestamp: Date.now() });
return;
}
if (this.spinner) {
this.spinner.stop();
const stream = this._getOutputStream();
if (stream.isTTY) {
stream.write('\r\x1b[2K');
}
this.spinner = null;
}
}Open data scored by Repobility · https://repobility.com
Logger.styled method · javascript · L446-L468 (23 LOC)src/utils/logger.js
styled(style, message, ...args) {
if (!this._shouldLog('info')) return;
const styles = {
bold: chalk.bold,
dim: chalk.dim,
italic: chalk.italic,
underline: chalk.underline,
inverse: chalk.inverse,
strikethrough: chalk.strikethrough,
};
const styleFunc = styles[style] || chalk.white;
const formatted = styleFunc(message);
this._getOutputStream().write(
(this._shouldColorize()
? formatted
: stripAnsi(typeof formatted === 'string' ? formatted : String(formatted ?? ''))) + '\n',
);
if (args.length > 0) {
this._getOutputStream().write(args.join(' ') + '\n');
}
}Logger.tree method · javascript · L473-L483 (11 LOC)src/utils/logger.js
tree(path, isLast = false, indent = '') {
if (!this._shouldLog('info')) return;
const connector = isLast ? '└── ' : '├── ';
const line = chalk.gray(indent + connector) + path;
this._getOutputStream().write(
(this._shouldColorize()
? line
: stripAnsi(typeof line === 'string' ? line : String(line ?? ''))) + '\n',
);
}Logger.child method · javascript · L488-L493 (6 LOC)src/utils/logger.js
child(prefix) {
return new Logger({
...this.options,
prefix: `${this.options.prefix}:${prefix}`,
});
}Logger.progress method · javascript · L526-L547 (22 LOC)src/utils/logger.js
progress(current, total, message = '') {
if (!this._shouldLog('info')) return;
const percentage = Math.round((current / total) * 100);
const progressMsg = `${percentage}% ${message}`;
const stream = this._getOutputStream();
if (stream.isTTY && this._effectiveFormat === 'text') {
const bar = this.createProgressBar(percentage);
stream.clearLine(0);
stream.cursorTo(0);
stream.write(`${bar} ${progressMsg}`);
if (current >= total) {
stream.write('\n');
}
} else {
if (current >= total) {
this.info(progressMsg);
}
}
}Logger.createProgressBar method · javascript · L552-L557 (6 LOC)src/utils/logger.js
createProgressBar(percentage, width = 30) {
const filled = Math.round((percentage / 100) * width);
const empty = width - filled;
return '[' + chalk.green('█'.repeat(filled)) + chalk.gray('░'.repeat(empty)) + ']';
}detectFenceLanguage function · javascript · L41-L46 (6 LOC)src/utils/markdown.js
function detectFenceLanguage(filePathOrExt = '') {
const ext = filePathOrExt.startsWith('.')
? filePathOrExt.toLowerCase()
: path.extname(filePathOrExt).toLowerCase();
return EXT_LANG_MAP.get(ext) || '';
}chooseFence function · javascript · L48-L55 (8 LOC)src/utils/markdown.js
function chooseFence(content) {
if (!content || typeof content !== 'string') return '```';
const matches = content.match(/`{3,}/g);
if (!matches) return '```';
const maxRun = matches.reduce((max, m) => Math.max(max, m.length), 3);
// Use a fence longer than any run found inside content
return '`'.repeat(Math.max(4, maxRun + 1));
}formatSmallMeta function · javascript · L61-L70 (10 LOC)src/utils/markdown.js
function formatSmallMeta({ size, modified, git, binaryLabel, truncatedAt }) {
const parts = [];
if (typeof size === 'number') parts.push(`Size: ${size.toLocaleString()} bytes`);
if (modified) parts.push(`Modified: ${modified}`);
if (git) parts.push(`Git: ${git}`);
if (binaryLabel) parts.push(`Binary: ${binaryLabel}`);
if (typeof truncatedAt === 'number')
parts.push(`Truncated at ${truncatedAt.toLocaleString()} chars`);
return `<small>${parts.join(' • ')}</small>`;
}Same scanner, your repo: https://repobility.com — Repobility
formatBeginMarker function · javascript · L78-L89 (12 LOC)src/utils/markdown.js
function formatBeginMarker(attrs) {
const kv = [];
for (const [key, val] of Object.entries(attrs)) {
if (val === undefined || val === null || val === '') continue;
if (typeof val === 'boolean' || typeof val === 'number') {
kv.push(`${key}=${val}`);
} else {
kv.push(`${key}=${quoteAttrValue(val)}`);
}
}
return `<!-- copytree:file-begin ${kv.join(' ')} -->`;
}readRules function · javascript · L31-L41 (11 LOC)src/utils/parallelWalker.js
async function readRules(filePath) {
try {
const content = await fs.readFile(filePath, 'utf8');
// Strip UTF-8 BOM if present
const cleaned = content.charCodeAt(0) === 0xfeff ? content.slice(1) : content;
return cleaned.split('\n');
} catch {
// File doesn't exist or can't be read - treat as no rules
return [];
}
}isIgnored function · javascript · L51-L91 (41 LOC)src/utils/parallelWalker.js
function isIgnored(absPath, root, layers, isDirectory = false) {
const relToRoot = toPosix(path.relative(root, absPath));
let ignored = false;
let matchedRule = null;
let matchedLayer = null;
for (const { base, ig } of layers) {
const relToLayer = toPosix(path.relative(base, absPath));
// Skip if path isn't under this layer's base
if (relToLayer.startsWith('..')) continue;
// Test with directory trailing slash if it's a directory
const testPath = isDirectory && !relToLayer.endsWith('/') ? relToLayer + '/' : relToLayer;
// Use .test() if available (returns {ignored, unignored}), otherwise fallback to .ignores()
const result = ig.test?.(testPath) ?? {
ignored: ig.ignores(testPath),
unignored: false,
};
if (result.ignored !== undefined) {
if (result.ignored) {
ignored = true;
matchedRule = 'exclude';
matchedLayer = base;
}
if (result.unignored) {
ignored = false;
matcheenqueueResult function · javascript · L161-L179 (19 LOC)src/utils/parallelWalker.js
async function enqueueResult(result) {
if (!result) return;
if (throttleEnabled) {
while (buffer.length >= maxBuffer) {
if (signal?.aborted) {
throw new Error('Traversal aborted');
}
if (!drainWaitPromise) {
drainWaitPromise = new Promise((resolve) => {
resolveDrainWait = resolve;
});
}
await drainWaitPromise;
}
}
buffer.push(result);
}notifyDrain function · javascript · L181-L189 (9 LOC)src/utils/parallelWalker.js
function notifyDrain() {
if (!throttleEnabled) return;
if (buffer.length < maxBuffer && resolveDrainWait) {
const resolve = resolveDrainWait;
resolveDrainWait = null;
drainWaitPromise = null;
resolve();
}
}shouldFollowSymlink function · javascript · L200-L210 (11 LOC)src/utils/parallelWalker.js
function shouldFollowSymlink(stat, absPath) {
if (!followSymlinks) return false;
const key = `${stat.dev}:${stat.ino}`;
if (visited.has(key)) {
// Cycle detected - skip
return false;
}
visited.add(key);
return true;
}processEntry function · javascript · L219-L330 (112 LOC)src/utils/parallelWalker.js
async function processEntry(dir, entry, layers, depth) {
if (signal?.aborted) {
throw new Error('Traversal aborted');
}
const absPath = path.join(dir, entry.name);
// Handle symlinks
let isDir = entry.isDirectory();
let stat = null;
if (entry.isSymbolicLink()) {
if (!followSymlinks) {
return; // Skip symlinks by default
}
try {
stat = await withFsRetry(() => fs.stat(absPath), {
...retryConfig,
onRetry: ({ code }) => recordRetry(absPath, code),
});
recordSuccessAfterRetry(absPath);
// Check for cycles
if (!shouldFollowSymlink(stat, absPath)) {
return; // Cycle detected or already visited
}
isDir = stat.isDirectory();
} catch (error) {
// Record failure and skip broken symlink
if (isRetryableFsError(error)) {
recordGiveUp(absPath, error.code);
} else {
recordPermanent(absPath, error.code)processDirectory function · javascript · L338-L379 (42 LOC)src/utils/parallelWalker.js
async function processDirectory(dir, layers, depth) {
stats.directoriesScanned++;
// Load ignore rules at this level
const ignoreFilePath = path.join(dir, ignoreFileName);
const localRules = await readRules(ignoreFilePath);
const localIg = ignore().add(localRules);
const nextLayers = [...layers, { base: dir, ig: localIg }];
let entries;
const readdirStart = Date.now();
try {
entries = await withFsRetry(() => fs.readdir(dir, { withFileTypes: true }), {
...retryConfig,
onRetry: ({ code }) => recordRetry(dir, code),
});
recordSuccessAfterRetry(dir);
} catch (error) {
// Record failure type based on error category
if (isRetryableFsError(error)) {
recordGiveUp(dir, error.code);
} else {
recordPermanent(dir, error.code);
}
// Can't read directory - skip it (return empty array for proper handling)
return [];
}
// Filter out ignore files themselves to preveCitation: Repobility (2026). State of AI-Generated Code. https://repobility.com/research/
getAllFilesParallel function · javascript · L459-L465 (7 LOC)src/utils/parallelWalker.js
export async function getAllFilesParallel(root, options = {}) {
const files = [];
for await (const file of walkParallel(root, options)) {
files.push(file);
}
return files;
}PerformanceMonitor.constructor method · javascript · L8-L19 (12 LOC)src/utils/performance.js
constructor(options = {}) {
this.options = {
enabled: options.enabled ?? process.env.NODE_ENV !== 'production',
logThreshold: options.logThreshold ?? 1000, // Log operations over 1s
memoryThreshold: options.memoryThreshold ?? 50 * 1024 * 1024, // 50MB
...options,
};
this.timers = new Map();
this.metrics = new Map();
this.logger = logger.child('Performance');
}PerformanceMonitor.startTimer method · javascript · L24-L31 (8 LOC)src/utils/performance.js
startTimer(name) {
if (!this.options.enabled) return;
this.timers.set(name, {
startTime: performance.now(),
startMemory: process.memoryUsage(),
});
}