52 lines
2.2 KiB
JavaScript
52 lines
2.2 KiB
JavaScript
// Claude Context panel: the current session's model, context-window use, cost
|
||||
|
|
// and edits, from the snapshot devdesk-statusline writes on every Claude update.
|
|||
|
|
|
|||
|
|
import { ago } from './sessions.js';
|
|||
|
|
|
|||
|
|
function compact(tokens) {
|
|||
|
|
if (tokens == null) return '—';
|
|||
|
|
if (tokens >= 1e6) return `${+(tokens / 1e6).toFixed(tokens % 1e6 ? 1 : 0)}M`;
|
|||
|
|
if (tokens >= 1e3) return `${Math.round(tokens / 1e3)}k`;
|
|||
|
|
return String(tokens);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export function renderContext(root, session, context) {
|
|||
|
|
const set = (field, text) => {
|
|||
|
|
const node = root.querySelector(`[data-field="${field}"]`);
|
|||
|
|
if (node) node.textContent = text;
|
|||
|
|
};
|
|||
|
|
const bar = root.querySelector('.lt-progress');
|
|||
|
|
const fill = root.querySelector('.lt-progress-bar');
|
|||
|
|
const note = root.querySelector('.dd-context-note');
|
|||
|
|
|
|||
|
|
if (!context) {
|
|||
|
|
root.dataset.state = 'empty';
|
|||
|
|
fill.style.width = '0%';
|
|||
|
|
bar.setAttribute('aria-valuenow', '0');
|
|||
|
|
for (const f of ['used', 'model', 'cost', 'lines', 'updated']) set(f, '—');
|
|||
|
|
note.textContent = session
|
|||
|
|
? 'No data yet: it appears once Claude has redrawn its status line in this session.'
|
|||
|
|
: 'Open a session to see its context.';
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const pct = context.used_pct;
|
|||
|
|
root.dataset.state = 'live';
|
|||
|
|
fill.style.width = `${Math.min(100, pct ?? 0)}%`;
|
|||
|
|
bar.setAttribute('aria-valuenow', String(Math.round(pct ?? 0)));
|
|||
|
|
bar.classList.remove('lt-progress--cyan', 'lt-progress--red');
|
|||
|
|
if (pct == null || pct < 70) bar.classList.add('lt-progress--cyan');
|
|||
|
|
else if (pct >= 90) bar.classList.add('lt-progress--red');
|
|||
|
|
|
|||
|
|
set('used', pct == null
|
|||
|
|
? `— / ${compact(context.window)}`
|
|||
|
|
: `${compact(context.used_tokens)} / ${compact(context.window)} (${pct.toFixed(pct < 10 ? 1 : 0)}%)`);
|
|||
|
|
set('model', [context.model, context.effort].filter(Boolean).join(' · ') || '—');
|
|||
|
|
set('cost', context.cost_usd == null ? '—' : `$${context.cost_usd.toFixed(2)}`);
|
|||
|
|
set('lines', `+${context.lines_added ?? 0} −${context.lines_removed ?? 0}`);
|
|||
|
|
set('updated', context.updated ? `${ago(context.updated)} ago`.replace('now ago', 'just now') : '—');
|
|||
|
|
note.textContent = pct != null && pct >= 80
|
|||
|
|
? 'Context is filling up; consider /compact or a new conversation.'
|
|||
|
|
: '';
|
|||
|
|
}
|