Skip to content
Merged
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
- Amp: parse bold Markdown usage labels from the latest CLI while preserving compatibility with older plain-text output (#3171).
- OpenCode Go: expose a Monthly % lane token for custom menu bar layouts once the monthly window has been observed (#3175).

### Performance
- OpenCodex: parse only newly appended usage-log entries instead of rebuilding the entire cache on every refresh, cutting memory use while preserving compatibility with older app versions (#3140). Thanks @olddonkey!

### Localization
- Turkish: improve translations throughout settings and provider views, including the previously untranslated iCloud sync section (#3178). Thanks @husodrn46!

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,11 @@ extension CostUsageStore {
requestedUntilDay: budgetProtectionWindow.untilKey,
calendar: calendar)
guard !result.catchUpRequired else { return result }
Self.identicalContentPreLockCheckpointForTesting?()
if let checkpoint = Self.identicalContentPreLockCheckpointForTesting,
checkpoint.databaseURL == self.databaseURL
{
checkpoint.checkpoint()
}
guard self.beginSaveTransaction() else {
var retry = result
retry.catchUpRequired = true
Expand Down
6 changes: 4 additions & 2 deletions Sources/CodexBarCore/Vendored/CostUsage/CostUsageStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,10 @@ actor CostUsageStore {
/// persisted file with the running count, so a crash-safety harness can SIGKILL the
/// process at a deterministic mid-save point. Never set in production.
nonisolated(unsafe) static var saveCycleCheckpointForTesting: ((Int) -> Void)?
/// Test-only interleaving point after optimistic identity succeeds and before its writer lock.
nonisolated(unsafe) static var identicalContentPreLockCheckpointForTesting: (() -> Void)?
/// Test-only interleaving point scoped to one database so parallel store fixtures stay isolated.
nonisolated(unsafe) static var identicalContentPreLockCheckpointForTesting: (
databaseURL: URL,
checkpoint: () -> Void)?

/// Test-only traversal proof for persisted Codex catch-up reconciliation. Never set in production.
nonisolated(unsafe) static var codexCatchUpReconciliationVisitForTesting: (() -> Void)?
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,56 @@
#if canImport(Darwin)
import Darwin
#elseif canImport(Glibc)
import Glibc
#elseif canImport(Musl)
import Musl
#endif
#if canImport(CryptoKit)
import CryptoKit
#else
import Crypto
#endif
import Foundation

public enum OpenCodexUsageParser {
private static let newline: UInt8 = 0x0A
/// Must match `OpenCodexUsageStore`'s prefix-digest window.
private static let prefixDigestByteLimit = 64 * 1024

struct ChangedUnderReadError: Error, Equatable {
let path: String
}

@TaskLocal static var logReadRecorderForTesting: LogReadRecorder?

final class LogReadRecorder: @unchecked Sendable {
private let lock = NSLock()
private var bytesRead: Int64 = 0
private var completeLines = 0

func record(bytes: Int64, lines: Int) {
self.lock.lock()
self.bytesRead += bytes
self.completeLines += lines
self.lock.unlock()
}

func snapshot() -> (bytesRead: Int64, completeLines: Int) {
self.lock.lock()
defer { self.lock.unlock() }
return (self.bytesRead, self.completeLines)
}
}

static func withLogReadRecorderForTesting<T>(
_ recorder: LogReadRecorder,
operation: () throws -> T) rethrows -> T
{
try self.$logReadRecorderForTesting.withValue(recorder) {
try operation()
}
}

public static func parseLine(_ line: String) -> OpenCodexUsageEntry? {
let trimmed = line.trimmingCharacters(in: .whitespacesAndNewlines)
guard !trimmed.isEmpty, let data = trimmed.data(using: .utf8) else { return nil }
Expand All @@ -15,14 +65,191 @@ public enum OpenCodexUsageParser {
}

public static func parseLines(_ text: String) -> [OpenCodexUsageEntry] {
text.split(whereSeparator: \.isNewline).compactMap { self.parseLine(String($0)) }
self.parseJSONL(Data(text.utf8), baseOffset: 0).entries
}

public static func parse(fileURL: URL, fileManager: FileManager = .default) throws -> [OpenCodexUsageEntry] {
guard fileManager.fileExists(atPath: fileURL.path) else { return [] }
let data = try Data(contentsOf: fileURL)
guard let text = String(data: data, encoding: .utf8) else { return [] }
return self.parseLines(text)
try self.parseLog(fileURL: fileURL, from: 0, fileManager: fileManager).entries
}

public static func parse(
fileURL: URL,
from offset: Int64,
fileManager: FileManager = .default) throws -> (entries: [OpenCodexUsageEntry], nextOffset: Int64)
{
let parsed = try self.parseLog(fileURL: fileURL, from: offset, fileManager: fileManager)
return (parsed.entries, parsed.nextOffset)
}

static func parseLog(
fileURL: URL,
from offset: Int64,
fileManager _: FileManager) throws -> JSONLParseResult
{
let handle: FileHandle
do {
handle = try FileHandle(forReadingFrom: fileURL)
} catch {
if Self.isConfirmedAbsence(error) {
return JSONLParseResult(
entries: [],
nextOffset: max(0, offset),
bytesRead: 0,
completeLineCount: 0,
newlineTerminatedEntryCount: 0)
}
throw error
}
defer { try? handle.close() }

var status = stat()
guard fstat(handle.fileDescriptor, &status) == 0 else {
throw Self.posixError(errno, path: fileURL.path)
}
let fileIdentity = "\(status.st_dev):\(status.st_ino)"
let size = Int64(status.st_size)
let startOffset = max(0, offset)
if startOffset > size {
throw ChangedUnderReadError(path: fileURL.path)
}

// Hold the snapshotted bytes instead of `.mappedIfSafe`. A mapping can SIGBUS if the
// file is truncated before those pages are touched; Swift cannot catch that. Full parse
// holds the file (~42 MB on a heavy machine) and only runs on a cold cache or rebuild.
// The steady-state path reads only the appended tail (`parsedOffset..<size`).
let byteCount = size - startOffset
let data: Data
if byteCount == 0 {
data = Data()
} else {
try handle.seek(toOffset: UInt64(startOffset))
data = try Self.readExact(handle, byteCount: byteCount, path: fileURL.path)
}

var parsed = self.parseJSONL(data, baseOffset: startOffset)
parsed.fileIdentity = fileIdentity
parsed.size = size
parsed.prefixDigest = try Self.prefixDigest(
handle: handle,
fileData: startOffset == 0 ? data : nil,
nextOffset: parsed.nextOffset,
path: fileURL.path)
self.logReadRecorderForTesting?.record(bytes: parsed.bytesRead, lines: parsed.completeLineCount)
return parsed
}

struct JSONLParseResult: Equatable, Sendable {
var entries: [OpenCodexUsageEntry]
var nextOffset: Int64
var bytesRead: Int64
var completeLineCount: Int
var newlineTerminatedEntryCount: Int
var fileIdentity: String?
var size: Int64
var prefixDigest: String

init(
entries: [OpenCodexUsageEntry],
nextOffset: Int64,
bytesRead: Int64,
completeLineCount: Int,
newlineTerminatedEntryCount: Int,
fileIdentity: String? = nil,
size: Int64 = 0,
prefixDigest: String = "")
{
self.entries = entries
self.nextOffset = nextOffset
self.bytesRead = bytesRead
self.completeLineCount = completeLineCount
self.newlineTerminatedEntryCount = newlineTerminatedEntryCount
self.fileIdentity = fileIdentity
self.size = size
self.prefixDigest = prefixDigest
}

var newlineTerminatedEntries: [OpenCodexUsageEntry] {
Array(self.entries.prefix(self.newlineTerminatedEntryCount))
}

var pendingTrailingEntries: [OpenCodexUsageEntry] {
Array(self.entries.dropFirst(self.newlineTerminatedEntryCount))
}
}

private static func parseJSONL(_ data: Data, baseOffset: Int64) -> JSONLParseResult {
var entries: [OpenCodexUsageEntry] = []
var completeLineCount = 0
var lineStart = data.startIndex
var lastCompleteEnd = data.startIndex
for newlineOffset in self.newlineOffsets(in: data) {
let newlineIndex = data.index(data.startIndex, offsetBy: newlineOffset)
if let entry = self.parseLineData(data[lineStart..<newlineIndex]) {
entries.append(entry)
}
completeLineCount += 1
lastCompleteEnd = data.index(after: newlineIndex)
lineStart = lastCompleteEnd
}
let newlineTerminatedEntryCount = entries.count
// Keep emitting a complete trailing record that has no terminating newline so a full parse
// of the same bytes stays identical, but leave nextOffset at the last LF. Advancing to EOF
// would desync incremental from a later append that glues bytes onto this record (`A` then
// `AB\n`). The sqlite cache only stores newline-terminated rows; the pending record is
// re-parsed on the next refresh.
if lineStart < data.endIndex, let entry = self.parseLineData(data[lineStart..<data.endIndex]) {
entries.append(entry)
completeLineCount += 1
}
let consumed = data.distance(from: data.startIndex, to: lastCompleteEnd)
return JSONLParseResult(
entries: entries,
nextOffset: baseOffset + Int64(consumed),
bytesRead: Int64(data.count),
completeLineCount: completeLineCount,
newlineTerminatedEntryCount: newlineTerminatedEntryCount)
}

private static func newlineOffsets(in data: Data) -> [Int] {
#if canImport(Darwin) || canImport(Glibc) || canImport(Musl)
let scanned: [Int]? = data.withUnsafeBytes { rawBuffer in
guard let baseAddress = rawBuffer.baseAddress else { return nil }
let count = rawBuffer.count
var offsets: [Int] = []
offsets.reserveCapacity(max(1, count / 64))
var searchStart = 0
while searchStart < count {
guard let found = memchr(
baseAddress.advanced(by: searchStart),
Int32(Self.newline),
count - searchStart)
else {
break
}
let newlineOffset = baseAddress.distance(to: UnsafeRawPointer(found))
offsets.append(newlineOffset)
searchStart = newlineOffset + 1
}
return offsets
}
if let scanned {
return scanned
}
#endif
var offsets: [Int] = []
var index = data.startIndex
while index < data.endIndex {
if data[index] == Self.newline {
offsets.append(data.distance(from: data.startIndex, to: index))
}
index = data.index(after: index)
}
return offsets
}

private static func parseLineData(_ line: Data) -> OpenCodexUsageEntry? {
guard let text = String(data: line, encoding: .utf8) else { return nil }
return self.parseLine(text)
}

private static func parse(_ object: [String: Any]) -> OpenCodexUsageEntry? {
Expand Down Expand Up @@ -125,4 +352,62 @@ public enum OpenCodexUsageParser {
}
return nil
}

private static func prefixDigest(
handle: FileHandle,
fileData: Data?,
nextOffset: Int64,
path: String) throws -> String
{
let length = min(Int64(Self.prefixDigestByteLimit), max(0, nextOffset))
let prefix: Data
if length == 0 {
prefix = Data()
} else if let fileData, Int64(fileData.count) >= length {
prefix = Data(fileData.prefix(Int(length)))
} else {
try handle.seek(toOffset: 0)
prefix = try Self.readExact(handle, byteCount: length, path: path)
}
return SHA256.hash(data: prefix).map { String(format: "%02x", $0) }.joined()
}

private static func readExact(_ handle: FileHandle, byteCount: Int64, path: String) throws -> Data {
let count = Int(byteCount)
var data = Data()
data.reserveCapacity(count)
while data.count < count {
let chunk = try handle.read(upToCount: count - data.count) ?? Data()
if chunk.isEmpty {
throw ChangedUnderReadError(path: path)
}
data.append(chunk)
}
return data
}

private static func isConfirmedAbsence(_ error: Error) -> Bool {
var current: Error? = error
while let err = current {
let nsError = err as NSError
if nsError.domain == NSPOSIXErrorDomain {
return nsError.code == Int(ENOENT) || nsError.code == Int(ENOTDIR)
}
if nsError.domain == NSCocoaErrorDomain,
nsError.code == CocoaError.fileReadNoSuchFile.rawValue
|| nsError.code == CocoaError.fileNoSuchFile.rawValue
{
return true
}
current = nsError.userInfo[NSUnderlyingErrorKey] as? Error
}
return false
}

private static func posixError(_ code: Int32, path: String) -> NSError {
NSError(
domain: NSPOSIXErrorDomain,
code: Int(code),
userInfo: [NSFilePathErrorKey: path])
}
}
Loading