mirror of
https://github.com/stablyai/orca.git
synced 2026-10-13 16:02:49 +00:00
refactor(usage): split AI-usage scanners and stores under the max-lines budget (#14668)
The three usage scanners and their stores, plus the renderer usage-overview model, each carried a file-level `eslint-disable max-lines` and had grown to 338-769 counted lines against a 300-line budget. AGENTS.md calls for splitting rather than suppressing, and config/max-lines-baseline.txt is a shrink-only ratchet, so this removes all seven suppressions and prunes their entries (341 -> 334). Each file is cut along the seams it already had -- and that several of the suppression comments named out loud: filesystem discovery / record parsing / attribution / aggregation for the scanners, and pricing policy / scope filters / rollups / session rows / automation attribution for the stores. Pure move, no behavior change. Code is relocated verbatim; the only edits are import plumbing and, where a private class method became a free function, the mechanical `this.state` -> `state` parameter threading. Every converted call site passes `this.state` at call time and the automation path takes a live `getState: () => this.state` getter, so no state is snapshotted. No barrel exports: each new module owns real logic and importers point at the owner. Verified: oxlint clean, ratchet passes, typecheck clean, full unit suite green (remaining failures are pre-existing load flakes in untouched files, each green when re-run serially), no import cycles among the 64 affected modules, and a statement-level diff of every split confirms the moves are verbatim.
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
import { stat } from 'node:fs/promises'
|
||||
import { basename, isAbsolute, join } from 'node:path'
|
||||
import { wslGatedReaddir, wslGatedStat } from '../native-chat/wsl-transcript-fs-access'
|
||||
import { WslTranscriptFsError } from '../native-chat/wsl-transcript-fs-gate'
|
||||
import { resolveOpenCodeDataDirectory } from '../opencode/opencode-data-directory'
|
||||
import type { OpenCodeUsageProcessedDatabase } from './types'
|
||||
|
||||
type OpenCodeDatabaseOverride = {
|
||||
isConfigured: boolean
|
||||
path: string | null
|
||||
}
|
||||
|
||||
function getOpenCodeDatabaseOverride(dataDirectory: string): OpenCodeDatabaseOverride {
|
||||
const raw = process.env.OPENCODE_DB?.trim()
|
||||
if (!raw) {
|
||||
return { isConfigured: false, path: null }
|
||||
}
|
||||
if (raw === ':memory:') {
|
||||
return { isConfigured: true, path: null }
|
||||
}
|
||||
return {
|
||||
isConfigured: true,
|
||||
path: isAbsolute(raw) ? raw : join(dataDirectory, raw)
|
||||
}
|
||||
}
|
||||
|
||||
// Why gated: the AI Vault's primary OpenCode source delegates here from inside
|
||||
// its discovery fan-out, so a UNC data dir or a UNC OPENCODE_DB on a stalled
|
||||
// distro would otherwise hang the whole scan on a raw syscall (STA-4049).
|
||||
export async function listOpenCodeDatabases(
|
||||
/** Lets a caller report the refusal; an empty list otherwise reads as
|
||||
* "OpenCode not used" rather than "we could not look". */
|
||||
onRefusal?: (path: string, error: WslTranscriptFsError) => void
|
||||
): Promise<string[]> {
|
||||
const dataDirectory = resolveOpenCodeDataDirectory()
|
||||
const databaseOverride = getOpenCodeDatabaseOverride(dataDirectory)
|
||||
if (databaseOverride.isConfigured) {
|
||||
if (!databaseOverride.path) {
|
||||
return []
|
||||
}
|
||||
try {
|
||||
return (await wslGatedStat(databaseOverride.path, 'scan')).isFile()
|
||||
? [databaseOverride.path]
|
||||
: []
|
||||
} catch (error) {
|
||||
reportRefusal(databaseOverride.path, error, onRefusal)
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const entries = await wslGatedReaddir(dataDirectory, 'scan')
|
||||
return entries
|
||||
.filter((entry) => entry.isFile() && /^opencode(?:-[A-Za-z0-9_.-]+)?\.db$/.test(entry.name))
|
||||
.map((entry) => join(dataDirectory, entry.name))
|
||||
.sort()
|
||||
} catch (error) {
|
||||
reportRefusal(dataDirectory, error, onRefusal)
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
function reportRefusal(
|
||||
path: string,
|
||||
error: unknown,
|
||||
onRefusal?: (path: string, error: WslTranscriptFsError) => void
|
||||
): void {
|
||||
if (error instanceof WslTranscriptFsError) {
|
||||
onRefusal?.(path, error)
|
||||
}
|
||||
}
|
||||
|
||||
export function compareOpenCodeClaimPriority(left: string, right: string): number {
|
||||
// Why: the canonical opencode.db is the live database; it must claim
|
||||
// duplicated sessions ahead of stale sibling copies. Remaining ties use
|
||||
// path order so ownership is deterministic across rescans.
|
||||
const leftRank = basename(left).toLowerCase() === 'opencode.db' ? 0 : 1
|
||||
const rightRank = basename(right).toLowerCase() === 'opencode.db' ? 0 : 1
|
||||
if (leftRank !== rightRank) {
|
||||
return leftRank - rightRank
|
||||
}
|
||||
return left < right ? -1 : left > right ? 1 : 0
|
||||
}
|
||||
|
||||
export async function getProcessedDatabaseInfo(
|
||||
dbPath: string
|
||||
): Promise<OpenCodeUsageProcessedDatabase> {
|
||||
const dbStat = await stat(dbPath)
|
||||
return {
|
||||
path: dbPath,
|
||||
mtimeMs: dbStat.mtimeMs,
|
||||
size: dbStat.size
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user