mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-04-06 01:03:32 +08:00
fix: improve error handling, fix bugs, and optimize core libraries
utils.js: - Fix countInFile: enforce global flag on regex to prevent silent under-counting (match() without /g returns only first match) - Add 5s timeout to readStdinJson to prevent hooks hanging forever - Handle EEXIST race condition in ensureDir - Pre-compile regex patterns in getGitModifiedFiles to avoid N*M compilations and catch invalid patterns before filtering - Add JSDoc documentation to all improved functions session-manager.js: - Fix getSessionById triple file read: pass pre-read content to getSessionStats instead of re-reading from disk - Allow getSessionStats to accept content string directly session-aliases.js: - Wrap temp file cleanup in try/catch to prevent cascading errors check-console-log.js: - Refactor to use shared utils (isGitRepo, getGitModifiedFiles, log) instead of raw execSync calls - Add exclusion patterns for test files, config files, and scripts/ where console.log is intentional session-end.js: - Log count of skipped unparseable transcript lines for diagnostics suggest-compact.js: - Guard against NaN from corrupted counter files package-manager.js: - Remove dead fallbackOrder parameter (unused after #162 fix)
This commit is contained in:
@@ -57,10 +57,20 @@ function getTempDir() {
|
||||
|
||||
/**
|
||||
* Ensure a directory exists (create if not)
|
||||
* @param {string} dirPath - Directory path to create
|
||||
* @returns {string} The directory path
|
||||
* @throws {Error} If directory cannot be created (e.g., permission denied)
|
||||
*/
|
||||
function ensureDir(dirPath) {
|
||||
if (!fs.existsSync(dirPath)) {
|
||||
fs.mkdirSync(dirPath, { recursive: true });
|
||||
try {
|
||||
if (!fs.existsSync(dirPath)) {
|
||||
fs.mkdirSync(dirPath, { recursive: true });
|
||||
}
|
||||
} catch (err) {
|
||||
// EEXIST is fine (race condition with another process creating it)
|
||||
if (err.code !== 'EEXIST') {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
return dirPath;
|
||||
}
|
||||
@@ -187,10 +197,29 @@ function findFiles(dir, pattern, options = {}) {
|
||||
|
||||
/**
|
||||
* Read JSON from stdin (for hook input)
|
||||
* @param {object} options - Options
|
||||
* @param {number} options.timeoutMs - Timeout in milliseconds (default: 5000).
|
||||
* Prevents hooks from hanging indefinitely if stdin never closes.
|
||||
* @returns {Promise<object>} Parsed JSON object, or empty object if stdin is empty
|
||||
*/
|
||||
async function readStdinJson() {
|
||||
async function readStdinJson(options = {}) {
|
||||
const { timeoutMs = 5000 } = options;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
let data = '';
|
||||
let settled = false;
|
||||
|
||||
const timer = setTimeout(() => {
|
||||
if (!settled) {
|
||||
settled = true;
|
||||
// Resolve with whatever we have so far rather than hanging
|
||||
try {
|
||||
resolve(data.trim() ? JSON.parse(data) : {});
|
||||
} catch {
|
||||
resolve({});
|
||||
}
|
||||
}
|
||||
}, timeoutMs);
|
||||
|
||||
process.stdin.setEncoding('utf8');
|
||||
process.stdin.on('data', chunk => {
|
||||
@@ -198,18 +227,22 @@ async function readStdinJson() {
|
||||
});
|
||||
|
||||
process.stdin.on('end', () => {
|
||||
if (settled) return;
|
||||
settled = true;
|
||||
clearTimeout(timer);
|
||||
try {
|
||||
if (data.trim()) {
|
||||
resolve(JSON.parse(data));
|
||||
} else {
|
||||
resolve({});
|
||||
}
|
||||
resolve(data.trim() ? JSON.parse(data) : {});
|
||||
} catch (err) {
|
||||
reject(err);
|
||||
}
|
||||
});
|
||||
|
||||
process.stdin.on('error', reject);
|
||||
process.stdin.on('error', err => {
|
||||
if (settled) return;
|
||||
settled = true;
|
||||
clearTimeout(timer);
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -313,7 +346,10 @@ function isGitRepo() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get git modified files
|
||||
* Get git modified files, optionally filtered by regex patterns
|
||||
* @param {string[]} patterns - Array of regex pattern strings to filter files.
|
||||
* Invalid patterns are silently skipped.
|
||||
* @returns {string[]} Array of modified file paths
|
||||
*/
|
||||
function getGitModifiedFiles(patterns = []) {
|
||||
if (!isGitRepo()) return [];
|
||||
@@ -324,12 +360,18 @@ function getGitModifiedFiles(patterns = []) {
|
||||
let files = result.output.split('\n').filter(Boolean);
|
||||
|
||||
if (patterns.length > 0) {
|
||||
files = files.filter(file => {
|
||||
return patterns.some(pattern => {
|
||||
const regex = new RegExp(pattern);
|
||||
return regex.test(file);
|
||||
});
|
||||
});
|
||||
// Pre-compile patterns, skipping invalid ones
|
||||
const compiled = [];
|
||||
for (const pattern of patterns) {
|
||||
try {
|
||||
compiled.push(new RegExp(pattern));
|
||||
} catch {
|
||||
// Skip invalid regex patterns
|
||||
}
|
||||
}
|
||||
if (compiled.length > 0) {
|
||||
files = files.filter(file => compiled.some(regex => regex.test(file)));
|
||||
}
|
||||
}
|
||||
|
||||
return files;
|
||||
@@ -349,12 +391,23 @@ function replaceInFile(filePath, search, replace) {
|
||||
|
||||
/**
|
||||
* Count occurrences of a pattern in a file
|
||||
* @param {string} filePath - Path to the file
|
||||
* @param {string|RegExp} pattern - Pattern to count. Strings are treated as
|
||||
* global regex patterns. RegExp instances are used as-is but the global
|
||||
* flag is enforced to ensure correct counting.
|
||||
* @returns {number} Number of matches found
|
||||
*/
|
||||
function countInFile(filePath, pattern) {
|
||||
const content = readFile(filePath);
|
||||
if (content === null) return 0;
|
||||
|
||||
const regex = pattern instanceof RegExp ? pattern : new RegExp(pattern, 'g');
|
||||
let regex;
|
||||
if (pattern instanceof RegExp) {
|
||||
// Ensure global flag is set for correct counting
|
||||
regex = pattern.global ? pattern : new RegExp(pattern.source, pattern.flags + 'g');
|
||||
} else {
|
||||
regex = new RegExp(pattern, 'g');
|
||||
}
|
||||
const matches = content.match(regex);
|
||||
return matches ? matches.length : 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user