mirror of
https://github.com/AgentSeal/codeburn.git
synced 2026-08-22 06:54:26 +00:00
- Period seg now uses the 5 real CLI periods (Today/7D/30D/Month/6M);
6M maps to 'all' (matches the menubar).
- Provider control is a real dropdown listing only DETECTED providers
(accumulated from current.providers so it never shrinks) + All.
- New RangeCalendar: month grid with click-and-drag range selection
(+ two-click fallback, future-date disabling) behind a calendar button;
commits a custom {from,to} threaded to Overview/Spend/Models/Optimize
via new --from/--to CLI args (Plans/Settings stay period-only).
- typecheck clean, 87 vitest pass.
35 lines
1.8 KiB
TypeScript
35 lines
1.8 KiB
TypeScript
import { contextBridge, ipcRenderer } from 'electron'
|
|
|
|
// Handlers resolve with { ok, value } | { ok, error } so the structured error
|
|
// `kind` survives the contextBridge boundary. `import type` is erased at build,
|
|
// so this shares main.ts's declaration without pulling its runtime in.
|
|
import type { Envelope } from './main'
|
|
|
|
type DateRange = { from: string; to: string }
|
|
|
|
async function invoke<T>(channel: string, ...args: unknown[]): Promise<T> {
|
|
const res = (await ipcRenderer.invoke(channel, ...args)) as Envelope<T>
|
|
if (res.ok) return res.value
|
|
// Reject with a plain object so `kind` is preserved (Error subclasses lose
|
|
// custom fields when cloned across worlds).
|
|
return Promise.reject(res.error)
|
|
}
|
|
|
|
// Shape matches CodeburnBridge (app/renderer/lib/types.ts); typing is enforced
|
|
// renderer-side where `window.codeburn` is declared as CodeburnBridge.
|
|
const bridge = {
|
|
getOverview: (period: string, provider: string, range?: DateRange) => invoke('codeburn:getOverview', period, provider, range),
|
|
getPlans: (period: string) => invoke('codeburn:getPlans', period),
|
|
getActReport: () => invoke('codeburn:getActReport'),
|
|
getModels: (period: string, provider: string, byTask: boolean, range?: DateRange) => invoke('codeburn:getModels', period, provider, byTask, range),
|
|
getYield: (period: string, range?: DateRange) => invoke('codeburn:getYield', period, range),
|
|
getSpendFlow: (period: string, provider: string, range?: DateRange) => invoke('codeburn:getSpendFlow', period, provider, range),
|
|
getDevices: (period: string) => invoke('codeburn:getDevices', period),
|
|
getDevicesScan: () => invoke('codeburn:getDevicesScan'),
|
|
getShareStatus: () => invoke('codeburn:getShareStatus'),
|
|
getIdentity: () => invoke('codeburn:getIdentity'),
|
|
cliStatus: () => invoke('codeburn:cliStatus'),
|
|
platform: process.platform,
|
|
}
|
|
|
|
contextBridge.exposeInMainWorld('codeburn', bridge)
|