Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions Sources/CodexBarCore/CodexLocalDataScope.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import Foundation

/// Resolves all local Codex sources as one scope. A managed Codex home must
/// never silently borrow an ambient state database or cache identity.
struct CodexLocalDataScope: Sendable, Equatable {
let identifier: String
let codexHome: URL
let sessionsRoot: URL
let archivedSessionsRoot: URL
let stateDatabaseURL: URL

static func resolve(options: CostUsageScanner.Options) -> CodexLocalDataScope {
if let sessionsRoot = options.codexSessionsRoot?.standardizedFileURL,
sessionsRoot.lastPathComponent == "sessions"
{
let home = sessionsRoot.deletingLastPathComponent()
return self.make(home: home)
}

let environment = ProcessInfo.processInfo.environment
if let sqliteHome = Self.nonEmpty(environment["CODEX_SQLITE_HOME"]) {
let home = URL(fileURLWithPath: sqliteHome, isDirectory: true).standardizedFileURL
return self.make(home: home)
}
if let codexHome = Self.nonEmpty(environment["CODEX_HOME"]) {
let home = URL(fileURLWithPath: codexHome, isDirectory: true).standardizedFileURL
return self.make(home: home)
}
return self.make(home: FileManager.default.homeDirectoryForCurrentUser.appendingPathComponent(".codex"))
}

func applying(to options: CostUsageScanner.Options) -> CostUsageScanner.Options {
var copy = options
copy.codexSessionsRoot = self.sessionsRoot
return copy
}

private static func make(home: URL) -> CodexLocalDataScope {
let standardizedHome = home.standardizedFileURL
return CodexLocalDataScope(
identifier: "codex-workspaces:" + Self.scopeFingerprint(standardizedHome.path),
codexHome: standardizedHome,
sessionsRoot: standardizedHome.appendingPathComponent("sessions", isDirectory: true),
archivedSessionsRoot: standardizedHome.appendingPathComponent("archived_sessions", isDirectory: true),
stateDatabaseURL: standardizedHome.appendingPathComponent("state_5.sqlite", isDirectory: false))
}

/// Stable local identifier for cache partitioning. It is not a security
/// primitive; it only prevents raw home paths from entering cache metadata.
private static func scopeFingerprint(_ value: String) -> String {
var hash: UInt64 = 14_695_981_039_346_656_037
for byte in value.utf8 {
hash ^= UInt64(byte)
hash &*= 1_099_511_628_211
}
return String(hash, radix: 16)
}

private static func nonEmpty(_ value: String?) -> String? {
let trimmed = value?.trimmingCharacters(in: .whitespacesAndNewlines)
return trimmed?.isEmpty == false ? trimmed : nil
}
}
64 changes: 64 additions & 0 deletions Sources/CodexBarCore/CodexLocalProjectRootResolver.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#if canImport(CryptoKit)
import CryptoKit
#else
import Crypto
#endif
import Foundation

public enum CodexLocalProjectRootResolver {
public typealias ProjectIdentity = (id: String, displayName: String, path: String?)

public static let chatsProjectId = "chats"
public static let chatsDisplayName = "Chats"

public static func projectIdentity(for cwd: String?) -> ProjectIdentity {
guard let cwd = cwd?.trimmingCharacters(in: .whitespacesAndNewlines), !cwd.isEmpty else {
return (self.chatsProjectId, self.chatsDisplayName, nil)
}

let root = self.resolveProjectRoot(from: URL(fileURLWithPath: cwd, isDirectory: true))
let canonicalRoot = self.canonicalProjectURL(root)
let path = canonicalRoot.path
return (
self.projectId(for: path),
canonicalRoot.lastPathComponent.isEmpty ? path : canonicalRoot.lastPathComponent,
path)
}

public static func resolveProjectRoot(from cwd: URL) -> URL {
let fm = FileManager.default
let loggedCWD = cwd.standardizedFileURL
var current = loggedCWD
var isDirectory: ObjCBool = false
let cwdExists = fm.fileExists(atPath: current.path, isDirectory: &isDirectory)
// A missing CWD is historical evidence. Do not walk up to an existing
// parent repository because that would collapse a deleted worktree or
// folder into a different project identity.
guard cwdExists else { return loggedCWD }
if cwdExists, !isDirectory.boolValue {
current = current.deletingLastPathComponent()
}

var candidate: URL? = current
while let url = candidate {
let gitURL = url.appendingPathComponent(".git")
if fm.fileExists(atPath: gitURL.path) {
return url.standardizedFileURL
}
let parent = url.deletingLastPathComponent()
candidate = parent.path == url.path ? nil : parent
}

return current.standardizedFileURL
}

private static func canonicalProjectURL(_ url: URL) -> URL {
url.resolvingSymlinksInPath().standardizedFileURL
}

public static func projectId(for path: String) -> String {
let digest = SHA256.hash(data: Data(path.utf8))
let hex = digest.map { String(format: "%02x", $0) }.joined()
return "project-\(hex.prefix(16))"
}
}
Loading