mirror of
https://github.com/AgentSeal/codeburn.git
synced 2026-05-07 13:48:40 +00:00
Merge pull request #36 from AgentSeal/fix/refresh-readme-changelog
feat: auto-refresh, updated README, changelog for 0.4.4
This commit is contained in:
commit
4c07c52fc4
5 changed files with 48 additions and 10 deletions
27
CHANGELOG.md
27
CHANGELOG.md
|
|
@ -1,5 +1,32 @@
|
|||
# Changelog
|
||||
|
||||
## 0.4.4 - 2026-04-15
|
||||
|
||||
### Added
|
||||
- Auto-refresh flag. `codeburn report --refresh 60` reloads data at a set
|
||||
interval. Works on `report`, `today`, and `month` commands. Default off.
|
||||
- Readable project names. Strips home directory prefix from encoded paths,
|
||||
shows 3 path segments for more context. Home dir sessions display as "home".
|
||||
- Responsive dashboard reflows on terminal resize via Ink's useWindowSize
|
||||
hook. Width cap raised from 104 to 160 columns. Contributed by @AleBles.
|
||||
- Total downloads and install size badges in README.
|
||||
|
||||
### Fixed
|
||||
- Agent/subagent session files were excluded, dropping ~46% of API calls.
|
||||
Subagent sessions live in separate subagents/ directories with unique
|
||||
message IDs and are now included. Closes #17.
|
||||
- Codex cache hit always showed 100%. OpenAI includes cached tokens inside
|
||||
input_tokens (unlike Anthropic). Normalized to prevent double-counting
|
||||
in cost calculation and cache hit display. Closes #21.
|
||||
- CSV formula injection. Cells starting with =, +, -, @ are prefixed with
|
||||
an apostrophe before CSV escaping. Contributed by @serabi.
|
||||
- Menubar "Open Full Report" and "Export CSV" actions broken for npm-installed
|
||||
users. Invokes resolved binary directly instead of assuming ~/codeburn
|
||||
checkout. Currency picker used nonexistent `config currency` subcommand.
|
||||
Contributed by @MukundaKatta. Closes #32, #27.
|
||||
- Activity panel moved from full-width to half-width row for better space
|
||||
usage on wide terminals.
|
||||
|
||||
## 0.4.1 - 2026-04-14
|
||||
|
||||
### Added
|
||||
|
|
|
|||
|
|
@ -8,7 +8,9 @@
|
|||
|
||||
<p align="center">
|
||||
<a href="https://www.npmjs.com/package/codeburn"><img src="https://img.shields.io/npm/v/codeburn.svg" alt="npm version" /></a>
|
||||
<a href="https://www.npmjs.com/package/codeburn"><img src="https://img.shields.io/npm/dm/codeburn.svg" alt="npm downloads" /></a>
|
||||
<a href="https://www.npmjs.com/package/codeburn"><img src="https://img.shields.io/npm/dt/codeburn.svg" alt="total downloads" /></a>
|
||||
<a href="https://www.npmjs.com/package/codeburn"><img src="https://img.shields.io/npm/dm/codeburn.svg" alt="monthly downloads" /></a>
|
||||
<a href="https://bundlephobia.com/package/codeburn"><img src="https://img.shields.io/bundlephobia/min/codeburn" alt="install size" /></a>
|
||||
<a href="https://github.com/agentseal/codeburn/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/codeburn.svg" alt="license" /></a>
|
||||
<a href="https://github.com/agentseal/codeburn"><img src="https://img.shields.io/badge/node-%3E%3D20-brightgreen.svg" alt="node version" /></a>
|
||||
</p>
|
||||
|
|
@ -45,6 +47,7 @@ codeburn # interactive dashboard (default: 7 days)
|
|||
codeburn today # today's usage
|
||||
codeburn month # this month's usage
|
||||
codeburn report -p 30days # rolling 30-day window
|
||||
codeburn report --refresh 60 # auto-refresh every 60 seconds
|
||||
codeburn status # compact one-liner (today + month)
|
||||
codeburn status --format json
|
||||
codeburn export # CSV with today, 7 days, 30 days
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 346 KiB After Width: | Height: | Size: 497 KiB |
|
|
@ -67,8 +67,9 @@ program
|
|||
.description('Interactive usage dashboard')
|
||||
.option('-p, --period <period>', 'Starting period: today, week, month, 30days', 'week')
|
||||
.option('--provider <provider>', 'Filter by provider: all, claude, codex', 'all')
|
||||
.option('--refresh <seconds>', 'Auto-refresh interval in seconds', parseInt)
|
||||
.action(async (opts) => {
|
||||
await renderDashboard(toPeriod(opts.period), opts.provider)
|
||||
await renderDashboard(toPeriod(opts.period), opts.provider, opts.refresh)
|
||||
})
|
||||
|
||||
function buildPeriodData(label: string, projects: ProjectSummary[]): PeriodData {
|
||||
|
|
@ -153,16 +154,18 @@ program
|
|||
.command('today')
|
||||
.description('Today\'s usage dashboard')
|
||||
.option('--provider <provider>', 'Filter by provider: all, claude, codex', 'all')
|
||||
.option('--refresh <seconds>', 'Auto-refresh interval in seconds', parseInt)
|
||||
.action(async (opts) => {
|
||||
await renderDashboard('today', opts.provider)
|
||||
await renderDashboard('today', opts.provider, opts.refresh)
|
||||
})
|
||||
|
||||
program
|
||||
.command('month')
|
||||
.description('This month\'s usage dashboard')
|
||||
.option('--provider <provider>', 'Filter by provider: all, claude, codex', 'all')
|
||||
.option('--refresh <seconds>', 'Auto-refresh interval in seconds', parseInt)
|
||||
.action(async (opts) => {
|
||||
await renderDashboard('month', opts.provider)
|
||||
await renderDashboard('month', opts.provider, opts.refresh)
|
||||
})
|
||||
|
||||
program
|
||||
|
|
|
|||
|
|
@ -194,18 +194,16 @@ const _homeEncoded = homedir().replace(/\//g, '-')
|
|||
function shortProject(encoded: string): string {
|
||||
let path = encoded.replace(/^-/, '')
|
||||
|
||||
// Strip home dir prefix (e.g. "Users-torukmakto-" → "")
|
||||
if (path.startsWith(_homeEncoded.replace(/^-/, ''))) {
|
||||
path = path.slice(_homeEncoded.replace(/^-/, '').length).replace(/^-/, '')
|
||||
}
|
||||
|
||||
// Strip common system prefixes
|
||||
path = path
|
||||
.replace(/^private-tmp-[^-]+-[^-]+-/, '') // /private/tmp/<org>/<env>/
|
||||
.replace(/^private-tmp-/, '')
|
||||
.replace(/^tmp-/, '')
|
||||
|
||||
if (!path) return '~'
|
||||
if (!path) return 'home'
|
||||
|
||||
const parts = path.split('-').filter(Boolean)
|
||||
if (parts.length <= 3) return parts.join('/')
|
||||
|
|
@ -485,10 +483,11 @@ function DashboardContent({ projects, period, columns }: { projects: ProjectSumm
|
|||
)
|
||||
}
|
||||
|
||||
function InteractiveDashboard({ initialProjects, initialPeriod, initialProvider }: {
|
||||
function InteractiveDashboard({ initialProjects, initialPeriod, initialProvider, refreshSeconds }: {
|
||||
initialProjects: ProjectSummary[]
|
||||
initialPeriod: Period
|
||||
initialProvider: string
|
||||
refreshSeconds?: number
|
||||
}) {
|
||||
const { exit } = useApp()
|
||||
const [period, setPeriod] = useState<Period>(initialPeriod)
|
||||
|
|
@ -528,6 +527,12 @@ function InteractiveDashboard({ initialProjects, initialPeriod, initialProvider
|
|||
setLoading(false)
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
if (!refreshSeconds || refreshSeconds <= 0) return
|
||||
const id = setInterval(() => { reloadData(period, activeProvider) }, refreshSeconds * 1000)
|
||||
return () => clearInterval(id)
|
||||
}, [refreshSeconds, period, activeProvider, reloadData])
|
||||
|
||||
const switchPeriod = useCallback(async (newPeriod: Period) => {
|
||||
if (newPeriod === period) return
|
||||
setPeriod(newPeriod)
|
||||
|
|
@ -592,7 +597,7 @@ function StaticDashboard({ projects, period }: { projects: ProjectSummary[]; per
|
|||
)
|
||||
}
|
||||
|
||||
export async function renderDashboard(period: Period = 'week', provider: string = 'all'): Promise<void> {
|
||||
export async function renderDashboard(period: Period = 'week', provider: string = 'all', refreshSeconds?: number): Promise<void> {
|
||||
await loadPricing()
|
||||
const range = getDateRange(period)
|
||||
const projects = await parseAllSessions(range, provider)
|
||||
|
|
@ -601,7 +606,7 @@ export async function renderDashboard(period: Period = 'week', provider: string
|
|||
|
||||
if (isTTY) {
|
||||
const { waitUntilExit } = render(
|
||||
<InteractiveDashboard initialProjects={projects} initialPeriod={period} initialProvider={provider} />
|
||||
<InteractiveDashboard initialProjects={projects} initialPeriod={period} initialProvider={provider} refreshSeconds={refreshSeconds} />
|
||||
)
|
||||
await waitUntilExit()
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue