fix: tighten types, remove dead exports, prevent FD leak

This commit is contained in:
iamtoruk 2026-04-20 15:52:18 -07:00 committed by AgentSeal
parent 7594fa0254
commit e18a1ef2f7
5 changed files with 25 additions and 26 deletions

View file

@ -143,9 +143,7 @@ async function atomicWriteJson(path: string, value: unknown): Promise<void> {
} catch (err) {
try {
await unlink(temp)
} catch {
// ignore cleanup failures
}
} catch {}
throw err
}
}

View file

@ -117,5 +117,7 @@ export async function* readSessionLinesFromOffset(filePath: string, startOffset:
for await (const line of rl) yield line
} catch (err) {
warn(`stream read failed for ${filePath}: ${(err as NodeJS.ErrnoException).code ?? 'unknown'}`)
} finally {
stream.destroy()
}
}

View file

@ -1,6 +1,7 @@
import { Chalk } from 'chalk'
import { stripVTControlCharacters } from 'node:util'
import { Chalk } from 'chalk'
import type { SourceProgressReporter } from './parser.js'
import { providerColor, providerLabel } from './provider-colors.js'

View file

@ -655,19 +655,19 @@ async function evaluateSourceManifestState(
if (!manifestEntry) {
const state: SourceManifestState = { source, parserVersion, manifestEntry, action: 'refresh', reason: 'missing-entry' }
logCacheDebug(source.provider, source.path, state.reason)
logCacheDebug(source.provider, source.path, state.reason!)
return state
}
if (manifestEntry.lastSeenParserVersion !== parserVersion) {
const state: SourceManifestState = { source, parserVersion, manifestEntry, action: 'refresh', reason: 'parser-version' }
logCacheDebug(source.provider, source.path, state.reason)
logCacheDebug(source.provider, source.path, state.reason!)
return state
}
if (source.cacheStrategy && manifestEntry.cacheStrategy && source.cacheStrategy !== manifestEntry.cacheStrategy) {
const state: SourceManifestState = { source, parserVersion, manifestEntry, action: 'refresh', reason: 'parser-version' }
logCacheDebug(source.provider, source.path, state.reason)
logCacheDebug(source.provider, source.path, state.reason!)
return state
}
@ -678,14 +678,14 @@ async function evaluateSourceManifestState(
if (!manifestEntry.fingerprint || manifestEntry.fingerprintPath !== fingerprintPath) {
const state: SourceManifestState = { source, parserVersion, manifestEntry, action: 'refresh', reason: 'fingerprint-miss' }
logCacheDebug(source.provider, source.path, state.reason)
logCacheDebug(source.provider, source.path, state.reason!)
return state
}
const currentFingerprint = await computeFileFingerprint(fingerprintPath).catch(() => null)
if (!currentFingerprint) {
const state: SourceManifestState = { source, parserVersion, manifestEntry, action: 'refresh', reason: 'fingerprint-miss' }
logCacheDebug(source.provider, source.path, state.reason)
logCacheDebug(source.provider, source.path, state.reason!)
return state
}
@ -720,7 +720,7 @@ async function evaluateSourceManifestState(
}
const state: SourceManifestState = { source, parserVersion, manifestEntry, action: 'refresh', reason: 'fingerprint-miss', currentFingerprint }
logCacheDebug(source.provider, source.path, state.reason)
logCacheDebug(source.provider, source.path, state.reason!)
return state
}
@ -779,7 +779,7 @@ async function refreshClaudeCacheUnit(
&& !!cached.appendState
&& cached.sessions.length > 0
&& !!state.currentFingerprint
if (shouldUseAppendOnly && manifestAppendState) {
if (shouldUseAppendOnly && manifestAppendState && cached?.appendState) {
if (
manifestAppendState.tailHash !== cached.appendState.tailHash
|| manifestAppendState.endOffset !== cached.appendState.endOffset
@ -789,7 +789,7 @@ async function refreshClaudeCacheUnit(
}
}
if (shouldUseAppendOnly && cached) {
if (shouldUseAppendOnly && cached && cached.appendState) {
addSeenDeduplicationKeysFromSessions(cached.sessions, localSeenMsgIds)
const appendedLines: string[] = []
for await (const line of readSessionLinesFromOffset(unit.path, cached.appendState.endOffset)) {

View file

@ -16,14 +16,14 @@ function traceCacheRead(op: string, filePath: string, note?: string): void {
const APPEND_TAIL_WINDOW_BYTES = 16 * 1024
export type SourceCacheStrategy = 'full-reparse' | 'append-jsonl'
type SourceCacheStrategy = 'full-reparse' | 'append-jsonl'
export type SourceFingerprint = {
type SourceFingerprint = {
mtimeMs: number
sizeBytes: number
}
export type AppendState = {
type AppendState = {
endOffset: number
tailHash: string
lastEntryType?: string
@ -59,18 +59,16 @@ export type SourceCacheManifestEntry = {
appendState?: AppendState
}
export type ReadSourceCacheEntryOptions = {
type ReadSourceCacheEntryOptions = {
allowStaleFingerprint?: boolean
}
export type SourceRange = {
type SourceRange = {
firstTimestamp?: string
lastTimestamp?: string
}
export type CachedSourcePlanHint = SourceCacheManifestEntry & SourceRange
export function sourceCacheKey(provider: string, logicalPath: string): string {
function sourceCacheKey(provider: string, logicalPath: string): string {
return `${provider}:${logicalPath}`
}
@ -174,18 +172,20 @@ function isParsedTurn(value: unknown): boolean {
&& typeof value.sessionId === 'string'
}
function isModelBreakdownEntry(value: unknown): boolean {
function isModelBreakdownEntry(value: unknown): value is { calls: number; costUSD: number; tokens: TokenUsage } {
return isPlainObject(value)
&& isFiniteNumber(value.calls)
&& isFiniteNumber(value.costUSD)
&& isTokenUsage(value.tokens)
}
function isCallsBreakdownEntry(value: unknown): boolean {
type TokenUsage = { inputTokens: number; outputTokens: number; cacheCreationInputTokens: number; cacheReadInputTokens: number; cachedInputTokens: number; reasoningTokens: number; webSearchRequests: number }
function isCallsBreakdownEntry(value: unknown): value is { calls: number } {
return isPlainObject(value) && isFiniteNumber(value.calls)
}
function isCategoryBreakdownEntry(value: unknown): boolean {
function isCategoryBreakdownEntry(value: unknown): value is { turns: number; costUSD: number; retries: number; editTurns: number; oneShotTurns: number } {
return isPlainObject(value)
&& isFiniteNumber(value.turns)
&& isFiniteNumber(value.costUSD)
@ -343,9 +343,7 @@ async function atomicWriteJson(path: string, value: unknown): Promise<void> {
} catch (err) {
try {
await unlink(temp)
} catch {
// ignore cleanup failures
}
} catch {}
throw err
}
}