@caius_kong/ccusage-dashboard 0.2.1 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +14 -0
  2. package/lib/index.html +20 -15
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -82,6 +82,20 @@ python3 lib/server.py --budget 300 # run server directly from the repo
82
82
  node bin/ccusage-ui.js # same as the npx experience
83
83
  ```
84
84
 
85
+ ## Releasing a new version
86
+
87
+ Releases are done entirely from the GitHub Actions tab (no local commands, full audit log):
88
+
89
+ 1. Push your code changes to `main` as usual.
90
+ 2. Go to **Actions → Publish to npm → Run workflow**.
91
+ 3. Leave **Version** empty to auto-bump a patch, or type a semver (e.g. `1.2.3`).
92
+ 4. The workflow bumps `package.json`, tags `v*`, pushes back to `main`, and publishes to npm.
93
+
94
+ You can also trigger it with the CLI:
95
+ ```bash
96
+ gh workflow run "Publish to npm" # bumps patch
97
+ ```
98
+
85
99
  ## License
86
100
 
87
101
  MIT © Caius Kong
package/lib/index.html CHANGED
@@ -23,6 +23,7 @@
23
23
  .tab{background:var(--panel);border:1px solid var(--border);border-radius:8px;padding:7px 16px;cursor:pointer;color:var(--muted);font-size:13px}
24
24
  .tab.active{background:var(--panel-2);border-color:var(--accent);color:var(--text);font-weight:600}
25
25
  .tab:hover{color:var(--text)}
26
+ .tab:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
26
27
  .tab-budget{margin-left:auto;display:flex;align-items:center;gap:10px}
27
28
  .budget-pill{border-radius:999px;padding:4px 12px;font-size:12px;font-weight:600;border:1px solid var(--border)}
28
29
  .budget-ok{color:var(--green);border-color:var(--border)}
@@ -49,7 +50,7 @@
49
50
  .err{color:var(--red)}
50
51
  .pill{background:var(--panel-2);border:1px solid var(--border);border-radius:999px;padding:1px 8px;font-size:11px;color:var(--muted);margin-left:6px}
51
52
  .hint{color:var(--muted);font-size:12px;margin-top:14px;text-align:center}
52
- .range{display:flex;gap:8px;align-items:center;margin-left:6px}
53
+ .range{display:flex;gap:8px;align-items:center;margin-left:6px;flex-wrap:wrap}
53
54
  .range input{background:var(--panel-2);border:1px solid var(--border);color:var(--text);border-radius:6px;padding:5px 8px;font-size:12px;font-family:inherit}
54
55
  .range button{background:var(--panel-2);border:1px solid var(--border);color:var(--text);border-radius:6px;padding:5px 12px;cursor:pointer;font-size:12px}
55
56
  .range button:hover{border-color:var(--accent)}
@@ -71,12 +72,12 @@
71
72
  <span class="status"><span class="dot" id="dot"></span><span id="status">connecting…</span></span>
72
73
  </header>
73
74
 
74
- <div class="tabs">
75
- <div class="tab active" data-tab="today">Today</div>
76
- <div class="tab" data-tab="week">This Week</div>
77
- <div class="tab" data-tab="month">This Month</div>
78
- <div class="tab" data-tab="range">Custom Range</div>
79
- <div class="tab" data-tab="sessions">Sessions</div>
75
+ <div class="tabs" role="tablist" aria-label="Time period">
76
+ <div class="tab active" role="tab" tabindex="0" aria-selected="true" data-tab="today">Today</div>
77
+ <div class="tab" role="tab" tabindex="0" aria-selected="false" data-tab="week">This Week</div>
78
+ <div class="tab" role="tab" tabindex="0" aria-selected="false" data-tab="month">This Month</div>
79
+ <div class="tab" role="tab" tabindex="0" aria-selected="false" data-tab="range">Custom Range</div>
80
+ <div class="tab" role="tab" tabindex="0" aria-selected="false" data-tab="sessions">Sessions</div>
80
81
  <div class="tab-budget">
81
82
  <span class="budget-pill" id="budgetPill">budget …</span>
82
83
  </div>
@@ -122,7 +123,7 @@
122
123
  <div id="sessionsList"><div class="empty">loading…</div></div>
123
124
  </div>
124
125
 
125
- <div class="hint">auto-refresh: today 15s · others 60s · costs in USD · <span id="lastUpd"></span></div>
126
+ <div class="hint">auto-refresh 15s · costs in USD · <span id="lastUpd"></span></div>
126
127
 
127
128
  <script>
128
129
  const $=(id)=>document.getElementById(id);
@@ -132,6 +133,7 @@ let active="today", modelCtx=[], sessDays=30;
132
133
  function fmtUsd(n){return "$"+(n==null?"–":Number(n).toFixed(2));}
133
134
  function fmtTok(n){
134
135
  if(n==null)return "–";
136
+ if(n>=1e9)return (n/1e9).toFixed(2)+"B";
135
137
  if(n>=1e6)return (n/1e6).toFixed(2)+"M";
136
138
  if(n>=1e3)return (n/1e3).toFixed(1)+"k";
137
139
  return String(n);
@@ -164,10 +166,10 @@ function applyBudget(month){
164
166
  fill.style.width=Math.min(pct,100)+"%";
165
167
  fill.className = pct>=100?"bg-danger":(pct>=80?"bg-warn":"bg-ok");
166
168
  $("budgetBand").style.display="flex";
167
- let cls="budget-ok",txt=`budget ${fmtUsd(cap)} · ${pct.toFixed(0)}%`;
168
- if(pct>=100){cls="budget-danger";txt=`⚠ ${fmtUsd(spent)} ≥ budget`;}
169
- else if(pct>=80){cls="budget-warn";txt=`${fmtUsd(spent)} / ${fmtUsd(cap)} (${pct.toFixed(0)}%)`;}
170
- const p=$("budgetPill");p.className="budget-pill "+cls;p.textContent=txt;
169
+ let cls="budget-ok",txt=`budget ${fmtUsd(cap)} · ${pct.toFixed(0)}%`,tip=`${fmtUsd(spent)} of ${fmtUsd(cap)} (${pct.toFixed(1)}%)`;
170
+ if(pct>=100){cls="budget-danger";txt=`⚠ ${fmtUsd(spent)} ≥ budget`;tip=`${fmtUsd(spent)} spent · ${pct.toFixed(1)}% of ${fmtUsd(cap)} budget`;}
171
+ else if(pct>=80){cls="budget-warn";txt=`${fmtUsd(spent)} / ${fmtUsd(cap)} (${pct.toFixed(0)}%)`;tip=`${fmtUsd(spent)} of ${fmtUsd(cap)} (${pct.toFixed(1)}%)`;}
172
+ const p=$("budgetPill");p.className="budget-pill "+cls;p.textContent=txt;p.title=tip;
171
173
  }
172
174
 
173
175
  async function loadSessions(){
@@ -302,9 +304,10 @@ async function tick(){
302
304
  }
303
305
 
304
306
  document.querySelectorAll(".tab").forEach(t=>{
305
- t.addEventListener("click",()=>{
306
- document.querySelectorAll(".tab").forEach(x=>x.classList.remove("active"));
307
+ const activate=()=>{
308
+ document.querySelectorAll(".tab").forEach(x=>{x.classList.remove("active");x.setAttribute("aria-selected","false");});
307
309
  t.classList.add("active");
310
+ t.setAttribute("aria-selected","true");
308
311
  active=t.dataset.tab;
309
312
  $("rangeRow").style.display = active==="range"?"block":"none";
310
313
  $("sessionsPanel").style.display = active==="sessions"?"block":"none";
@@ -316,7 +319,9 @@ document.querySelectorAll(".tab").forEach(t=>{
316
319
  }else{
317
320
  loadModels();
318
321
  }
319
- });
322
+ };
323
+ t.addEventListener("click",activate);
324
+ t.addEventListener("keydown",(e)=>{if(e.key==="Enter"||e.key===" "||e.key==="Spacebar"){e.preventDefault();activate();}});
320
325
  });
321
326
  $("rangeGo").addEventListener("click",rangeApply);
322
327
  document.querySelectorAll(".sday").forEach(b=>{
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@caius_kong/ccusage-dashboard",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "One-command local dashboard for ccusage: today/week/month/custom cost by model, 30-day trend, monthly budget alert. Numbers straight from ccusage.",
5
5
  "license": "MIT",
6
6
  "type": "commonjs",