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:
Affaan Mustafa
2026-02-12 07:06:53 -08:00
parent b2285e870a
commit 18c5a76a96
7 changed files with 134 additions and 54 deletions

View File

@@ -143,11 +143,21 @@ function parseSessionMetadata(content) {
/**
* Calculate statistics for a session
* @param {string} sessionPath - Full path to session file
* @param {string} sessionPathOrContent - Full path to session file, OR
* the pre-read content string (to avoid redundant disk reads when
* the caller already has the content loaded).
* @returns {object} Statistics object
*/
function getSessionStats(sessionPath) {
const content = getSessionContent(sessionPath);
function getSessionStats(sessionPathOrContent) {
// Accept pre-read content string to avoid redundant file reads.
// If the argument looks like a file path (no newlines, ends with .tmp),
// read from disk. Otherwise treat it as content.
const content = (typeof sessionPathOrContent === 'string' &&
!sessionPathOrContent.includes('\n') &&
sessionPathOrContent.endsWith('.tmp'))
? getSessionContent(sessionPathOrContent)
: sessionPathOrContent;
const metadata = parseSessionMetadata(content);
return {
@@ -281,7 +291,8 @@ function getSessionById(sessionId, includeContent = false) {
if (includeContent) {
session.content = getSessionContent(sessionPath);
session.metadata = parseSessionMetadata(session.content);
session.stats = getSessionStats(sessionPath);
// Pass pre-read content to avoid a redundant disk read
session.stats = getSessionStats(session.content || '');
}
return session;