diff --git a/src/index.ts b/src/index.ts index 2bb4023..f698543 100644 --- a/src/index.ts +++ b/src/index.ts @@ -416,9 +416,12 @@ function usageEmoji(pct: number): string { return 'ðŸŸĒ'; } -function formatResetKST(iso: string): string { +function formatResetKST(value: string | number): string { try { - return new Date(iso).toLocaleString('ko-KR', { + // Handle unix timestamp (seconds) or ISO string + const date = + typeof value === 'number' ? new Date(value * 1000) : new Date(value); + return date.toLocaleString('ko-KR', { timeZone: 'Asia/Seoul', month: 'short', day: 'numeric', @@ -426,7 +429,7 @@ function formatResetKST(iso: string): string { minute: '2-digit', }); } catch { - return iso; + return String(value); } } @@ -544,9 +547,10 @@ interface ClaudeUsageData { } interface CodexRateLimit { - limitName: string; - primary: { usedPercent: number; resetsAt: string }; - secondary: { usedPercent: number; resetsAt: string }; + limitId?: string; + limitName: string | null; + primary: { usedPercent: number; resetsAt: string | number }; + secondary: { usedPercent: number; resetsAt: string | number }; } async function fetchClaudeUsage(): Promise { @@ -635,7 +639,13 @@ async function fetchCodexUsage(): Promise { }) + '\n', ); } else if (msg.id === 2 && msg.result) { - finish(msg.result); + // Extract rate limits from rateLimitsByLimitId object + const byId = msg.result.rateLimitsByLimitId; + if (byId && typeof byId === 'object') { + finish(Object.values(byId) as CodexRateLimit[]); + } else { + finish(null); + } } } catch { /* non-JSON line, skip */ @@ -659,8 +669,6 @@ async function fetchCodexUsage(): Promise { async function buildUsageContent(): Promise { const lines: string[] = []; - lines.push(`📊 **Usage ëģīęģ ** (${ASSISTANT_NAME})`); - lines.push(''); // Fetch API usage in parallel const [claudeUsage, codexUsage] = await Promise.all([ @@ -695,11 +703,12 @@ async function buildUsageContent(): Promise { for (const limit of codexUsage) { const p = Math.round(limit.primary.usedPercent); const s = Math.round(limit.secondary.usedPercent); + const name = limit.limitName || limit.limitId || 'Codex'; lines.push( - `â€Ē ${limit.limitName} 5ė‹œę°„: ${usageEmoji(p)} ${p}% (ëĶŽė…‹: ${formatResetKST(limit.primary.resetsAt)})`, + `â€Ē ${name} 5ė‹œę°„: ${usageEmoji(p)} ${p}% (ëĶŽė…‹: ${formatResetKST(limit.primary.resetsAt)})`, ); lines.push( - `â€Ē ${limit.limitName} 7ėž: ${usageEmoji(s)} ${s}% (ëĶŽė…‹: ${formatResetKST(limit.secondary.resetsAt)})`, + `â€Ē ${name} 7ėž: ${usageEmoji(s)} ${s}% (ëĶŽė…‹: ${formatResetKST(limit.secondary.resetsAt)})`, ); } lines.push(''); @@ -745,9 +754,9 @@ async function buildUsageContent(): Promise { } lines.push(diskLine); - lines.push(`â€Ē ė—…íƒ€ėž„: ${formatElapsed(process.uptime() * 1000)}`); + lines.push(`â€Ē ė—…íƒ€ėž„: ${formatElapsed(os.uptime() * 1000)}`); - return lines.join('\n') + `\n\n_${new Date().toLocaleTimeString('ko-KR')}_`; + return lines.join('\n') + `\n\n_${new Date().toLocaleTimeString('ko-KR', { hour: '2-digit', minute: '2-digit' })}_`; } // ── Dashboard Lifecycle ─────────────────────────────────────────