import { SqliteAdapter as Database } from './sqlite-adapter.js'; export type PathKind = "config" | "data" | "state" | "cache"; export interface PathsResolverOptions { app: string; internal?: boolean; platform?: string; home?: string; env?: Record; } export declare function dataDir(options: PathsResolverOptions): string; /** The resolver (XDG / macOS) CACHE root for an app; `HASNA_CACHE_HOME` overrides it. */ export declare function cacheDir(options: PathsResolverOptions): string; import type { EconomyRequest, EconomySession, EconomyProject, CostCenter, CostCenterBreakdown, CostCenterKind, Budget, BudgetStatus, CostSummary, ZeroCostModelBreakdown, ModelBreakdown, ProjectBreakdown, AgentBreakdown, AccountBreakdown, Period, Agent, SessionFilter } from '../types/index.js'; export declare function getMachineId(): string; /** * Resolve the user's home directory: $HOME, then $USERPROFILE (Windows), then * the OS user database. A home that cannot be resolved is a hard error — never * a literal "~" path (relative to cwd) and never an "undefined"-prefixed path. */ export declare function getHomeDir(): string; /** * The @hasna/paths-resolved (XDG / macOS home layout) data root for economy. * This is the forward-looking home the XDG migration (hotfixes plan * `0f49f56a`, task P3.3) moves the store toward: `~/.local/share/hasna/economy` * on Linux, `~/Library/Application Support/Hasna/economy` on macOS. The home * override mirrors the pre-existing $HOME-first resolution so the resolver * follows the same home the legacy path does. */ export declare function getResolverDataRoot(): string; /** The legacy (pre-XDG) data root: ~/.hasna/economy */ export declare function getLegacyDataRoot(): string; /** * Whether the resolver (XDG) data root should be adopted as the effective data * root. The resolver root is adopted only when the operator has set * `HASNA_DATA_HOME` (the data-kind override — a deliberate opt-in to the XDG * layout) or the store has already been physically migrated there * (`economy.db` exists). A machine that only redirects another kind (e.g. * cache to tmpfs) must NOT have its data home moved, and a live store at the * legacy home must never become invisible on upgrade. */ export declare function adoptResolverDataRoot(resolved: string, env?: Record): boolean; /** The exact-app override root, when set: `HASNA_ECONOMY_HOME`, then `ECONOMY_HOME`. */ export declare function getExactDataRoot(): string | undefined; /** * The effective data root for economy: an exact-app override * (`HASNA_ECONOMY_HOME`, then `ECONOMY_HOME`) wins unconditionally; otherwise * the resolver (XDG) data root once adopted; otherwise the legacy * `~/.hasna/economy` default — an existing store never becomes invisible on * upgrade. The store path (`HASNA_ECONOMY_DB_PATH` / `ECONOMY_DB`) is layered * on top of this by `getDbPath`, so an explicit store path always wins * regardless. The legacy `~/.economy` files are auto-migrated into the * effective root, preserving the historical behavior. */ export declare function getDataDir(): string; export declare function getDbPath(): string; export declare function openDatabase(dbPath?: string, skipSeed?: boolean): Database; export declare function upsertCostCenter(db: Database, center: CostCenter): void; export declare function getCostCenter(db: Database, id: string): CostCenter | null; export declare function upsertRequest(db: Database, req: EconomyRequest): void; export declare function upsertSession(db: Database, session: EconomySession): void; export declare function rollupSession(db: Database, sessionId: string): void; export declare function querySessions(db: Database, filter?: SessionFilter): EconomySession[]; export declare function queryTopSessions(db: Database, n?: number, agent?: string, since?: string): EconomySession[]; export declare function querySummary(db: Database, period: Period, machine?: string, allMachines?: boolean, agent?: Agent): CostSummary; export declare function queryZeroCostTokenizedModels(db: Database, limit?: number): ZeroCostModelBreakdown[]; export declare function queryModelBreakdown(db: Database): ModelBreakdown[]; export declare function queryAgentBreakdown(db: Database, period?: Period, machine?: string): AgentBreakdown[]; export declare function queryProjectBreakdown(db: Database, period?: Period, machine?: string): ProjectBreakdown[]; export declare function queryAccountBreakdown(db: Database, period?: Period, machine?: string): AccountBreakdown[]; export declare function queryCostCenterBreakdown(db: Database, period?: Period, filter?: { kind?: CostCenterKind; machine?: string; since?: string; }): CostCenterBreakdown[]; export declare function queryProjectBreakdownSince(db: Database, since: string, machine?: string): ProjectBreakdown[]; export declare function queryAgentBreakdownSince(db: Database, since: string): AgentBreakdown[]; export declare function queryModelBreakdownSince(db: Database, since: string): ModelBreakdown[]; export declare function queryAccountBreakdownSince(db: Database, since: string): AccountBreakdown[]; export declare function queryDailyBreakdown(db: Database, days?: number, machine?: string): Array<{ date: string; cost_usd: number; agent: string; }>; export declare function queryHourlyBreakdown(db: Database, machine?: string, hours?: number): Array<{ hour: string; cost_usd: number; agent: string; }>; export declare function upsertProject(db: Database, project: EconomyProject): void; export declare function getProject(db: Database, path: string): EconomyProject | null; export declare function listProjects(db: Database): EconomyProject[]; export declare function deleteProject(db: Database, path: string): void; export declare function upsertBudget(db: Database, budget: Budget): void; export declare function listBudgets(db: Database): Budget[]; export declare function deleteBudget(db: Database, id: string): void; export declare function getBudgetStatuses(db: Database): BudgetStatus[]; export interface Goal { id: string; period: 'day' | 'week' | 'month' | 'year'; project_path: string | null; agent: string | null; limit_usd: number; created_at: string; updated_at: string; } export interface GoalStatus extends Goal { current_spend_usd: number; percent_used: number; is_on_track: boolean; is_at_risk: boolean; is_over: boolean; } export declare function upsertGoal(db: Database, goal: Goal): void; export declare function deleteGoal(db: Database, id: string): void; export declare function listGoals(db: Database): Goal[]; export declare function getGoalStatuses(db: Database): GoalStatus[]; export declare function getIngestState(db: Database, source: string, key: string): string | null; /** * Load every ingest_state row for one source into a Map. Ingest loops that * check one key per corpus file (e.g. tens of thousands of session jsonl * files) must use this instead of calling getIngestState per file — one * prepared query per file turns an O(n) scan into an O(n) query blowup that * dominates the whole ingest pass. */ export declare function loadIngestState(db: Database, source: string): Map; export declare function setIngestState(db: Database, source: string, key: string, value: string): void; export declare function queryRequestsSince(db: Database, since: string): EconomyRequest[]; export interface FeedbackRecord { message: string; email?: string | null; category?: string | null; version?: string | null; machine_id?: string | null; } /** Persist a feedback row. Used by both the LocalStore and the serve endpoint. */ export declare function insertFeedback(db: Database, record: FeedbackRecord): void; export interface BillingDaily { date: string; provider: 'anthropic' | 'openai' | string; description: string; cost_usd: number; updated_at: string; } export declare function upsertBillingDaily(db: Database, row: BillingDaily): void; export declare function clearBillingRange(db: Database, provider: string, fromDate: string, toDate: string): void; export declare function queryBillingSummary(db: Database, period: Period): { total_usd: number; by_provider: Record; }; /** * How many provider billing rows exist for a period. A $0.00 actual total is * ambiguous on its own — it is produced both by "billing agrees with telemetry * at zero" and by "billing was never imported" — and only this count separates * them. */ export declare function countBillingRecords(db: Database, period: Period): number; export interface SessionDetail { session: Record; requests: Array>; } /** * Fetch a single session (by exact id or id-prefix) plus its per-request rows, * ordered oldest-first. Returns null when no session matches. Backs the CLI * `session ` command and the MCP `get_session_detail` tool via the Store. */ export declare function getSessionDetail(db: Database, id: string): SessionDetail | null; export interface MachineInfo { machine_id: string; sessions: number; requests: number; total_cost_usd: number; last_active: string; } export declare function listMachines(db: Database, period?: Period): MachineInfo[]; export interface DbModelPricing { model: string; input_per_1m: number; output_per_1m: number; cache_read_per_1m: number; cache_write_per_1m: number; cache_write_1h_per_1m?: number; cache_storage_per_1m_hour?: number; updated_at: string; } export declare function upsertModelPricing(db: Database, p: DbModelPricing): void; export declare function getModelPricing(db: Database, model: string): DbModelPricing | null; export declare function listModelPricing(db: Database): DbModelPricing[]; export declare function deleteModelPricing(db: Database, model: string): void; export declare function seedModelPricing(db: Database, defaults: Record): void; export declare function upsertSubscription(db: Database, sub: import('../types/index.js').Subscription): void; export declare function listSubscriptions(db: Database): import('../types/index.js').Subscription[]; export declare function deleteSubscription(db: Database, id: string): void; export declare function upsertUsageSnapshot(db: Database, snap: Omit & { id?: string; updated_at?: string; }): void; export declare function queryUsageSnapshots(db: Database, opts?: { agent?: string; date?: string; since?: string; }): import('../types/index.js').UsageSnapshot[]; export declare function listMachineRegistry(db: Database): import('../types/index.js').MachineRegistry[]; export declare function dedupeRequests(db: Database): number; export declare function bulkIngest(db: Database, body: Record): { ingested: Record; total: number; }; //# sourceMappingURL=database.d.ts.map