mirror of
https://github.com/AgentSeal/codeburn.git
synced 2026-08-12 10:04:49 +00:00
perf: lazy-load cursor provider to eliminate startup overhead
Cursor module (sqlite.ts, better-sqlite3) now only loads when cursor provider is actually requested. Claude/Codex startup is unaffected -- cursor import never happens unless needed.
This commit is contained in:
parent
3c439cb28f
commit
b7b7b2c7d6
5 changed files with 61 additions and 19 deletions
|
|
@ -6,7 +6,7 @@ import { renderStatusBar } from './format.js'
|
|||
import { installMenubar, renderMenubarFormat, type PeriodData, type ProviderCost, uninstallMenubar } from './menubar.js'
|
||||
import { CATEGORY_LABELS, type DateRange, type ProjectSummary, type TaskCategory } from './types.js'
|
||||
import { renderDashboard } from './dashboard.js'
|
||||
import { providers } from './providers/index.js'
|
||||
import { getAllProviders } from './providers/index.js'
|
||||
import { readConfig, saveConfig, getConfigFilePath } from './config.js'
|
||||
import { createRequire } from 'node:module'
|
||||
|
||||
|
|
@ -130,7 +130,7 @@ program
|
|||
const weekData = buildPeriodData('7 Days', await parseAllSessions(getDateRange('week').range, pf))
|
||||
const monthData = buildPeriodData('Month', await parseAllSessions(getDateRange('month').range, pf))
|
||||
const todayProviders: ProviderCost[] = []
|
||||
for (const p of providers) {
|
||||
for (const p of await getAllProviders()) {
|
||||
const data = await parseAllSessions(todayRange, p.name)
|
||||
const cost = data.reduce((s, proj) => s + proj.totalCostUSD, 0)
|
||||
if (cost > 0) todayProviders.push({ name: p.displayName, cost })
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import { CATEGORY_LABELS, type ProjectSummary, type TaskCategory } from './types
|
|||
import { formatCost, formatTokens } from './format.js'
|
||||
import { parseAllSessions } from './parser.js'
|
||||
import { loadPricing } from './models.js'
|
||||
import { providers } from './providers/index.js'
|
||||
import { getAllProviders } from './providers/index.js'
|
||||
|
||||
type Period = 'today' | 'week' | 'month' | '30days' | '90days'
|
||||
|
||||
|
|
@ -391,10 +391,15 @@ function BashBreakdown({ projects, pw, bw }: { projects: ProjectSummary[]; pw: n
|
|||
)
|
||||
}
|
||||
|
||||
const PROVIDER_DISPLAY_NAMES: Record<string, string> = {
|
||||
all: 'All',
|
||||
claude: 'Claude',
|
||||
codex: 'Codex',
|
||||
cursor: 'Cursor',
|
||||
}
|
||||
|
||||
function getProviderDisplayName(name: string): string {
|
||||
if (name === 'all') return 'All'
|
||||
const provider = providers.find(p => p.name === name)
|
||||
return provider?.displayName ?? name
|
||||
return PROVIDER_DISPLAY_NAMES[name] ?? name
|
||||
}
|
||||
|
||||
function PeriodTabs({ active, providerName, showProvider }: {
|
||||
|
|
@ -514,7 +519,8 @@ function InteractiveDashboard({ initialProjects, initialPeriod, initialProvider,
|
|||
let cancelled = false
|
||||
async function detect() {
|
||||
const found: string[] = []
|
||||
for (const p of providers) {
|
||||
const allProviders = await getAllProviders()
|
||||
for (const p of allProviders) {
|
||||
const sessions = await p.discoverSessions()
|
||||
if (sessions.length > 0) found.push(p.name)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,36 @@
|
|||
import { claude } from './claude.js'
|
||||
import { codex } from './codex.js'
|
||||
import { cursor } from './cursor.js'
|
||||
import type { Provider, SessionSource } from './types.js'
|
||||
|
||||
export const providers: Provider[] = [claude, codex, cursor]
|
||||
let cursorProvider: Provider | null = null
|
||||
let cursorLoadAttempted = false
|
||||
|
||||
async function loadCursor(): Promise<Provider | null> {
|
||||
if (cursorLoadAttempted) return cursorProvider
|
||||
cursorLoadAttempted = true
|
||||
try {
|
||||
const { cursor } = await import('./cursor.js')
|
||||
cursorProvider = cursor
|
||||
return cursor
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
const coreProviders: Provider[] = [claude, codex]
|
||||
|
||||
export async function getAllProviders(): Promise<Provider[]> {
|
||||
const cursor = await loadCursor()
|
||||
return cursor ? [...coreProviders, cursor] : [...coreProviders]
|
||||
}
|
||||
|
||||
export const providers = coreProviders
|
||||
|
||||
export async function discoverAllSessions(providerFilter?: string): Promise<SessionSource[]> {
|
||||
const allProviders = await getAllProviders()
|
||||
const filtered = providerFilter && providerFilter !== 'all'
|
||||
? providers.filter(p => p.name === providerFilter)
|
||||
: providers
|
||||
? allProviders.filter(p => p.name === providerFilter)
|
||||
: allProviders
|
||||
const all: SessionSource[] = []
|
||||
for (const provider of filtered) {
|
||||
const sessions = await provider.discoverSessions()
|
||||
|
|
@ -18,6 +40,8 @@ export async function discoverAllSessions(providerFilter?: string): Promise<Sess
|
|||
}
|
||||
|
||||
export function getProvider(name: string): Provider | undefined {
|
||||
return providers.find(p => p.name === name)
|
||||
return cursorProvider?.name === name
|
||||
? cursorProvider
|
||||
: coreProviders.find(p => p.name === name)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,14 @@
|
|||
import { describe, it, expect } from 'vitest'
|
||||
import { providers } from '../src/providers/index.js'
|
||||
import { providers, getAllProviders } from '../src/providers/index.js'
|
||||
|
||||
describe('provider registry', () => {
|
||||
it('has all providers registered', () => {
|
||||
expect(providers.map(p => p.name)).toEqual(['claude', 'codex', 'cursor'])
|
||||
it('has core providers registered synchronously', () => {
|
||||
expect(providers.map(p => p.name)).toEqual(['claude', 'codex'])
|
||||
})
|
||||
|
||||
it('includes cursor after async load', async () => {
|
||||
const all = await getAllProviders()
|
||||
expect(all.map(p => p.name)).toEqual(['claude', 'codex', 'cursor'])
|
||||
})
|
||||
|
||||
it('claude tool display names are identity', () => {
|
||||
|
|
@ -33,8 +38,9 @@ describe('provider registry', () => {
|
|||
expect(claude.modelDisplayName('claude-sonnet-4-6')).toBe('Sonnet 4.6')
|
||||
})
|
||||
|
||||
it('cursor model display names handle auto mode', () => {
|
||||
const cursor = providers.find(p => p.name === 'cursor')!
|
||||
it('cursor model display names handle auto mode', async () => {
|
||||
const all = await getAllProviders()
|
||||
const cursor = all.find(p => p.name === 'cursor')!
|
||||
expect(cursor.modelDisplayName('default')).toBe('Auto (Sonnet est.)')
|
||||
expect(cursor.modelDisplayName('claude-4.5-opus-high-thinking')).toBe('Opus 4.5 (Thinking)')
|
||||
expect(cursor.modelDisplayName('grok-code-fast-1')).toBe('Grok Code Fast')
|
||||
|
|
|
|||
|
|
@ -1,7 +1,13 @@
|
|||
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
||||
import { providers } from '../../src/providers/index.js'
|
||||
import { getAllProviders } from '../../src/providers/index.js'
|
||||
import type { Provider } from '../../src/providers/types.js'
|
||||
|
||||
const cursorProvider = providers.find(p => p.name === 'cursor')!
|
||||
let cursorProvider: Provider
|
||||
|
||||
beforeEach(async () => {
|
||||
const all = await getAllProviders()
|
||||
cursorProvider = all.find(p => p.name === 'cursor')!
|
||||
})
|
||||
|
||||
describe('cursor provider', () => {
|
||||
it('is registered', () => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue