sidekick-agent-hub 0.12.10 → 0.13.1
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.
- package/README.md +18 -1
- package/dist/sidekick-cli.mjs +167 -46
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -27,7 +27,7 @@ Requires **Node.js 20+**.
|
|
|
27
27
|
|
|
28
28
|
```bash
|
|
29
29
|
sidekick dashboard [options]
|
|
30
|
-
sidekick tasks|decisions|notes|stats|handoff|search|context [options]
|
|
30
|
+
sidekick tasks|decisions|notes|stats|quota|handoff|search|context [options]
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
The standalone commands open the dashboard directly to a specific panel or run a one-shot query. All accept `--project` and `--provider` flags.
|
|
@@ -77,6 +77,23 @@ Global flags `--project` and `--provider` also apply.
|
|
|
77
77
|
|
|
78
78
|
You can also press `r` in the TUI dashboard to generate a report for the current session.
|
|
79
79
|
|
|
80
|
+
## Subscription Quota
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
sidekick quota
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Check Claude Max / Claude Code subscription quota utilization. Shows 5-hour and 7-day windows with color-coded progress bars and reset countdowns.
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
Subscription Quota
|
|
90
|
+
──────────────────────────────────────────────────
|
|
91
|
+
5-Hour ████████████░░░░░░░░░░░░░░░░░░ 40% resets in 2h 15m
|
|
92
|
+
7-Day ██████████████████████░░░░░░░░ 72% resets in 4d 6h
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Use `--json` for machine-readable output. Requires Claude Code credentials (`~/.claude/.credentials.json`).
|
|
96
|
+
|
|
80
97
|
## Dashboard Panels
|
|
81
98
|
|
|
82
99
|
The dashboard is a two-pane terminal UI. The left side shows a navigable list, the right side shows details for the selected item.
|
package/dist/sidekick-cli.mjs
CHANGED
|
@@ -8251,8 +8251,6 @@ var require_codexDatabase = __commonJS({
|
|
|
8251
8251
|
}
|
|
8252
8252
|
isAvailable() {
|
|
8253
8253
|
try {
|
|
8254
|
-
if (!fs10.existsSync(this.dbPath))
|
|
8255
|
-
return false;
|
|
8256
8254
|
return fs10.statSync(this.dbPath).size > 0;
|
|
8257
8255
|
} catch {
|
|
8258
8256
|
return false;
|
|
@@ -8275,15 +8273,19 @@ var require_codexDatabase = __commonJS({
|
|
|
8275
8273
|
query(sql, params = []) {
|
|
8276
8274
|
if (!this.sqlite3Available)
|
|
8277
8275
|
return [];
|
|
8278
|
-
let
|
|
8279
|
-
|
|
8280
|
-
if (
|
|
8281
|
-
|
|
8282
|
-
|
|
8283
|
-
|
|
8284
|
-
|
|
8285
|
-
|
|
8286
|
-
|
|
8276
|
+
let paramIndex = 0;
|
|
8277
|
+
const query = sql.replace(/\?/g, () => {
|
|
8278
|
+
if (paramIndex >= params.length)
|
|
8279
|
+
return "?";
|
|
8280
|
+
const param = params[paramIndex++];
|
|
8281
|
+
if (typeof param === "number") {
|
|
8282
|
+
if (!Number.isFinite(param))
|
|
8283
|
+
return "0";
|
|
8284
|
+
return String(param);
|
|
8285
|
+
}
|
|
8286
|
+
const escaped = String(param).replace(/'/g, "''");
|
|
8287
|
+
return `'${escaped}'`;
|
|
8288
|
+
});
|
|
8287
8289
|
try {
|
|
8288
8290
|
const result = (0, child_process_1.execFileSync)("sqlite3", ["-json", "-readonly", this.dbPath, query], {
|
|
8289
8291
|
encoding: "utf-8",
|
|
@@ -18746,19 +18748,18 @@ var init_StaticDataLoader = __esm({
|
|
|
18746
18748
|
import * as fs2 from "fs";
|
|
18747
18749
|
import * as path from "path";
|
|
18748
18750
|
import * as os from "os";
|
|
18749
|
-
var REFRESH_MS, USAGE_URL, BETA_HEADER,
|
|
18751
|
+
var REFRESH_MS, USAGE_URL, BETA_HEADER, FIVE_HOUR_MS, SEVEN_DAY_MS, QuotaService;
|
|
18750
18752
|
var init_QuotaService = __esm({
|
|
18751
18753
|
"src/dashboard/QuotaService.ts"() {
|
|
18752
18754
|
"use strict";
|
|
18753
18755
|
REFRESH_MS = 3e4;
|
|
18754
18756
|
USAGE_URL = "https://api.anthropic.com/api/oauth/usage";
|
|
18755
18757
|
BETA_HEADER = "oauth-2025-04-20";
|
|
18756
|
-
|
|
18758
|
+
FIVE_HOUR_MS = 5 * 36e5;
|
|
18759
|
+
SEVEN_DAY_MS = 7 * 864e5;
|
|
18757
18760
|
QuotaService = class {
|
|
18758
18761
|
_interval = null;
|
|
18759
18762
|
_cached = null;
|
|
18760
|
-
_fiveHourHistory = [];
|
|
18761
|
-
_sevenDayHistory = [];
|
|
18762
18763
|
_callback = null;
|
|
18763
18764
|
/** Register a callback for quota updates. */
|
|
18764
18765
|
onUpdate(cb) {
|
|
@@ -18781,6 +18782,41 @@ var init_QuotaService = __esm({
|
|
|
18781
18782
|
getCached() {
|
|
18782
18783
|
return this._cached;
|
|
18783
18784
|
}
|
|
18785
|
+
/** Single fetch — no polling, includes elapsed-time projections. */
|
|
18786
|
+
async fetchOnce() {
|
|
18787
|
+
const token = await this.readToken();
|
|
18788
|
+
if (!token) {
|
|
18789
|
+
return { fiveHour: { utilization: 0, resetsAt: "" }, sevenDay: { utilization: 0, resetsAt: "" }, available: false, error: "no-credentials" };
|
|
18790
|
+
}
|
|
18791
|
+
try {
|
|
18792
|
+
const res = await fetch(USAGE_URL, {
|
|
18793
|
+
method: "GET",
|
|
18794
|
+
headers: {
|
|
18795
|
+
"Authorization": `Bearer ${token}`,
|
|
18796
|
+
"anthropic-beta": BETA_HEADER,
|
|
18797
|
+
"Content-Type": "application/json"
|
|
18798
|
+
}
|
|
18799
|
+
});
|
|
18800
|
+
if (!res.ok) {
|
|
18801
|
+
const error = res.status === 401 ? "auth-failed" : `API error: ${res.status}`;
|
|
18802
|
+
return { fiveHour: { utilization: 0, resetsAt: "" }, sevenDay: { utilization: 0, resetsAt: "" }, available: false, error };
|
|
18803
|
+
}
|
|
18804
|
+
const data = await res.json();
|
|
18805
|
+
const fiveUtil = data.five_hour?.utilization ?? 0;
|
|
18806
|
+
const sevenUtil = data.seven_day?.utilization ?? 0;
|
|
18807
|
+
const fiveResetsAt = data.five_hour?.resets_at ?? "";
|
|
18808
|
+
const sevenResetsAt = data.seven_day?.resets_at ?? "";
|
|
18809
|
+
return {
|
|
18810
|
+
fiveHour: { utilization: fiveUtil, resetsAt: fiveResetsAt },
|
|
18811
|
+
sevenDay: { utilization: sevenUtil, resetsAt: sevenResetsAt },
|
|
18812
|
+
available: true,
|
|
18813
|
+
projectedFiveHour: this.projectFromElapsed(fiveUtil, fiveResetsAt, FIVE_HOUR_MS),
|
|
18814
|
+
projectedSevenDay: this.projectFromElapsed(sevenUtil, sevenResetsAt, SEVEN_DAY_MS)
|
|
18815
|
+
};
|
|
18816
|
+
} catch {
|
|
18817
|
+
return { fiveHour: { utilization: 0, resetsAt: "" }, sevenDay: { utilization: 0, resetsAt: "" }, available: false, error: "network-error" };
|
|
18818
|
+
}
|
|
18819
|
+
}
|
|
18784
18820
|
async fetchQuota() {
|
|
18785
18821
|
const token = await this.readToken();
|
|
18786
18822
|
if (!token) {
|
|
@@ -18809,16 +18845,14 @@ var init_QuotaService = __esm({
|
|
|
18809
18845
|
const data = await res.json();
|
|
18810
18846
|
const fiveUtil = data.five_hour?.utilization ?? 0;
|
|
18811
18847
|
const sevenUtil = data.seven_day?.utilization ?? 0;
|
|
18812
|
-
this.addHistory(this._fiveHourHistory, fiveUtil);
|
|
18813
|
-
this.addHistory(this._sevenDayHistory, sevenUtil);
|
|
18814
18848
|
const fiveResetsAt = data.five_hour?.resets_at ?? "";
|
|
18815
18849
|
const sevenResetsAt = data.seven_day?.resets_at ?? "";
|
|
18816
18850
|
this.emit({
|
|
18817
18851
|
fiveHour: { utilization: fiveUtil, resetsAt: fiveResetsAt },
|
|
18818
18852
|
sevenDay: { utilization: sevenUtil, resetsAt: sevenResetsAt },
|
|
18819
18853
|
available: true,
|
|
18820
|
-
projectedFiveHour: this.
|
|
18821
|
-
projectedSevenDay: this.
|
|
18854
|
+
projectedFiveHour: this.projectFromElapsed(fiveUtil, fiveResetsAt, FIVE_HOUR_MS),
|
|
18855
|
+
projectedSevenDay: this.projectFromElapsed(sevenUtil, sevenResetsAt, SEVEN_DAY_MS)
|
|
18822
18856
|
});
|
|
18823
18857
|
} catch {
|
|
18824
18858
|
if (this._cached?.available) return;
|
|
@@ -18843,25 +18877,13 @@ var init_QuotaService = __esm({
|
|
|
18843
18877
|
return null;
|
|
18844
18878
|
}
|
|
18845
18879
|
}
|
|
18846
|
-
|
|
18847
|
-
|
|
18848
|
-
|
|
18849
|
-
|
|
18850
|
-
|
|
18851
|
-
if (
|
|
18852
|
-
|
|
18853
|
-
const newest = history[history.length - 1];
|
|
18854
|
-
const diffMs = newest.timestamp - oldest.timestamp;
|
|
18855
|
-
if (diffMs < 3e4) return null;
|
|
18856
|
-
const diffUtil = newest.utilization - oldest.utilization;
|
|
18857
|
-
if (diffUtil <= 0) return 0;
|
|
18858
|
-
return diffUtil / (diffMs / 6e4);
|
|
18859
|
-
}
|
|
18860
|
-
project(current, resetsAt, rate) {
|
|
18861
|
-
if (rate === null || rate <= 0 || !resetsAt) return void 0;
|
|
18862
|
-
const timeToResetMs = new Date(resetsAt).getTime() - Date.now();
|
|
18863
|
-
if (timeToResetMs <= 0) return void 0;
|
|
18864
|
-
return Math.min(current + rate * (timeToResetMs / 6e4), 200);
|
|
18880
|
+
projectFromElapsed(utilization, resetsAt, windowMs) {
|
|
18881
|
+
if (!resetsAt || utilization <= 0) return void 0;
|
|
18882
|
+
const resetTime = new Date(resetsAt).getTime();
|
|
18883
|
+
const now = Date.now();
|
|
18884
|
+
const elapsed = windowMs - (resetTime - now);
|
|
18885
|
+
if (elapsed <= 0) return void 0;
|
|
18886
|
+
return Math.min(Math.round(utilization * (windowMs / elapsed)), 200);
|
|
18865
18887
|
}
|
|
18866
18888
|
};
|
|
18867
18889
|
}
|
|
@@ -18898,7 +18920,7 @@ var init_UpdateCheckService = __esm({
|
|
|
18898
18920
|
/** Run the update check (one-shot). */
|
|
18899
18921
|
async check() {
|
|
18900
18922
|
try {
|
|
18901
|
-
const current = "0.
|
|
18923
|
+
const current = "0.13.1";
|
|
18902
18924
|
const cached = this.readCache();
|
|
18903
18925
|
let latest;
|
|
18904
18926
|
if (cached && Date.now() - cached.checkedAt < CACHE_TTL_MS) {
|
|
@@ -20469,10 +20491,18 @@ ${hint}{/grey-fg}`;
|
|
|
20469
20491
|
lines.push("", sectionHeader("Quota", w2));
|
|
20470
20492
|
const fiveColor = getUtilizationColor(q.fiveHour.utilization);
|
|
20471
20493
|
const fiveBar = makeColorBar(q.fiveHour.utilization, 18, fiveColor);
|
|
20472
|
-
|
|
20494
|
+
const fiveProj = q.projectedFiveHour != null ? (() => {
|
|
20495
|
+
const pc = getUtilizationColor(q.projectedFiveHour);
|
|
20496
|
+
return ` {grey-fg}\u2192{/grey-fg} {${pc}-fg}${q.projectedFiveHour.toFixed(0)}%{/${pc}-fg}`;
|
|
20497
|
+
})() : "";
|
|
20498
|
+
lines.push(` {grey-fg}5h{/grey-fg} ${fiveBar} {bold}${q.fiveHour.utilization.toFixed(0)}%{/bold}${fiveProj}`);
|
|
20473
20499
|
const sevenColor = getUtilizationColor(q.sevenDay.utilization);
|
|
20474
20500
|
const sevenBar = makeColorBar(q.sevenDay.utilization, 18, sevenColor);
|
|
20475
|
-
|
|
20501
|
+
const sevenProj = q.projectedSevenDay != null ? (() => {
|
|
20502
|
+
const pc = getUtilizationColor(q.projectedSevenDay);
|
|
20503
|
+
return ` {grey-fg}\u2192{/grey-fg} {${pc}-fg}${q.projectedSevenDay.toFixed(0)}%{/${pc}-fg}`;
|
|
20504
|
+
})() : "";
|
|
20505
|
+
lines.push(` {grey-fg}7d{/grey-fg} ${sevenBar} {bold}${q.sevenDay.utilization.toFixed(0)}%{/bold}${sevenProj}`);
|
|
20476
20506
|
}
|
|
20477
20507
|
const attrLines = renderContextAttribution(m.contextAttribution);
|
|
20478
20508
|
if (attrLines.length > 0) {
|
|
@@ -59446,7 +59476,7 @@ function StatusBar({
|
|
|
59446
59476
|
] }),
|
|
59447
59477
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { dimColor: true, children: [
|
|
59448
59478
|
" v",
|
|
59449
|
-
"0.
|
|
59479
|
+
"0.13.1"
|
|
59450
59480
|
] }),
|
|
59451
59481
|
updateInfo && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { color: "yellow", children: [
|
|
59452
59482
|
" (v",
|
|
@@ -59829,7 +59859,7 @@ function ChangelogOverlay({ entries, scrollOffset }) {
|
|
|
59829
59859
|
" ",
|
|
59830
59860
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Text, { bold: true, color: "cyan", children: [
|
|
59831
59861
|
"Terminal Dashboard v",
|
|
59832
|
-
"0.
|
|
59862
|
+
"0.13.1"
|
|
59833
59863
|
] }),
|
|
59834
59864
|
latestDate ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Text, { color: "gray", children: [
|
|
59835
59865
|
" \u2014 ",
|
|
@@ -60184,7 +60214,7 @@ var init_mouse = __esm({
|
|
|
60184
60214
|
var CHANGELOG_default;
|
|
60185
60215
|
var init_CHANGELOG = __esm({
|
|
60186
60216
|
"CHANGELOG.md"() {
|
|
60187
|
-
CHANGELOG_default = '# Changelog\n\nAll notable changes to the Sidekick Agent Hub CLI will be documented in this file.\n\nThe format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),\nand this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n\n## [0.12.10] - 2026-03-01\n\n### Added\n\n- **Events Panel** (key 7): Scrollable live event stream with colored type badges (`[USR]`, `[AST]`, `[TOOL]`, `[RES]`), timestamps, and keyword-highlighted summaries; detail tabs for full event JSON and surrounding context\n- **Charts Panel** (key 8): Tool frequency horizontal bars, event type distribution, 60-minute activity heatmap using `\u2591\u2592\u2593\u2588` intensity characters, and pattern analysis with frequency bars and template text\n- **Multi-Mode Filter**: `/` filter overlay now supports four modes \u2014 substring, fuzzy, regex, and date range \u2014 Tab cycles modes, regex mode shows red validation errors\n- **Search Term Highlighting**: Active filter terms highlighted in blue within side list items\n- **Timeline Keyword Coloring**: Event summaries in the Sessions panel Timeline tab now use semantic keyword coloring \u2014 errors red, success green, tool names cyan, file paths magenta\n\n### Removed\n\n- **Search Panel**: Removed redundant Search panel (previously key 7) \u2014 the `/` filter with multi-mode support serves the same purpose\n\n## [0.12.9] - 2026-02-28\n\n### Added\n\n- **Standalone Data Commands**: `sidekick tasks`, `sidekick decisions`, `sidekick notes`, `sidekick stats`, `sidekick handoff` for accessing project data without launching the TUI\n- **`sidekick search <query>`**: Cross-session full-text search from the terminal\n- **`sidekick context`**: Composite output of tasks, decisions, notes, and handoff for piping into other tools\n- **`--list` flag on `sidekick dump`**: Discover available session IDs before requiring `--session <id>`\n- **Search Panel**: Search panel (panel 7) wired into the TUI dashboard\n\n### Changed\n\n- **`taskMerger` utility**: Duplicate `mergeTasks` logic extracted into shared `taskMerger` utility\n- **Model constants**: Hardcoded model IDs extracted to named constants\n\n### Fixed\n\n- **`convention` icon**: Notes panel icon replaced with valid `tip` type\n- **Linux clipboard**: Now supports Wayland (`wl-copy`) and `xsel` fallbacks, with error messages instead of silent failure\n- **`provider.dispose()`**: Added to `dump` and `report` commands (prevents SQLite connection leaks)\n\n## [0.12.8] - 2026-02-28\n\n### Changed\n\n- **Dashboard UI/UX Polish**: Visual overhaul for better hierarchy, consistency, and readability\n - Splash screen and help overlay now display the robot ASCII logo\n - Toast notifications show severity icons (\u2718 error, \u26A0 warning, \u25CF info) with inner padding\n - Focused pane uses double-border for clear focus indication\n - Section dividers (`\u2500\u2500 Title \u2500\u2500\u2500\u2500`) replace bare bold headers in summary, agents, and context attribution\n - Tab bar: active tab underlined in magenta, inactive tabs dimmed, bracket syntax removed\n - Status bar: segmented layout with `\u2502` separators; keys bold, labels dim\n - Summary metrics condensed: elapsed/events/compactions on one line, tokens on one line with cache rate and cost\n - Sparklines display peak metadata annotations\n - Progress bars use blessed color tags for consistent coloring\n - Help overlay uses dot-leader alignment for all keybinding rows\n - Empty state hints per panel (e.g. "Tasks appear as your agent works.")\n - Session picker groups sessions by provider with section headers when multiple providers are present\n\n## [0.12.7] - 2026-02-27\n\n### Added\n\n- **HTML Session Report**: `sidekick report` command generates a self-contained HTML report and opens it in the default browser\n - Options: `--session`, `--output`, `--theme` (dark/light), `--no-open`, `--no-thinking`\n - TUI Dashboard: press `r` to generate and open an HTML report for the current session\n\n## [0.12.6] - 2026-02-26\n\n### Added\n\n- **Session Dump Command**: `sidekick dump` exports session data in text, markdown, or JSON format with `--format`, `--width`, and `--expand` options\n- **Plans Panel Re-enabled**: Plans panel restored in CLI dashboard with plan file discovery from `~/.claude/plans/`\n- **Enhanced Status Bar**: Session info display improved with richer metadata\n\n### Fixed\n\n- **Old snapshot format migration**: Restoring pre-0.12.3 session snapshots no longer shows empty timeline entries\n\n### Changed\n\n- **Phrase library moved to shared**: CLI-specific phrase formatting kept local, all phrase content now from `sidekick-shared`\n\n## [0.12.5] - 2026-02-24\n\n### Fixed\n\n- **Update check too slow to notice new versions**: Reduced npm registry cache TTL from 24 hours to 4 hours so upgrade notices appear sooner after a new release\n\n## [0.12.4] - 2026-02-24\n\n### Fixed\n\n- **Session crash on upgrade**: Fixed `d.timestamp.getTime is not a function` error when restoring tool call data from session snapshots \u2014 `Date` objects were serialized to strings by JSON but not rehydrated on restore, causing the session monitor to crash on first run after upgrading from 0.12.2 to 0.12.3\n\n## [0.12.3] - 2026-02-24\n\n### Added\n\n- **Latest-node indicator**: The most recently added node in tree and boxed mind map views is now marked with a yellow indicator\n- **Plan analytics in mind map**: Tree and boxed views now display plan progress and per-step metrics\n - Tree view: plan header shows completion stats; steps show complexity, duration, tokens, tool calls, and errors in metadata brackets\n - Box view: progress bar with completion percentage; steps show right-aligned metrics; subtitle shows step count and total duration\n- **Cross-provider plan extraction**: Shared `PlanExtractor` now handles Claude Code (EnterPlanMode/ExitPlanMode) and OpenCode (`<proposed_plan>` XML) plans \u2014 previously only Codex plans were shown\n- **Enriched plan data model**: Plan steps include duration, token count, tool call count, and error messages\n- **Phase-grouped plan display**: When a plan has phase structure, tree and boxed views group steps under phase headers with context lines from the original plan markdown\n- **Node type filter**: Press `f` on the Mind Map tab to cycle through node type filters (file, tool, task, subagent, command, plan, knowledge-note) \u2014 non-matching sections render dimmed in grey\n\n### Fixed\n\n- **Kanban board regression**: Subagent and plan-step tasks now correctly appear in the kanban board\n\n### Changed\n\n- **Plans panel temporarily disabled**: The Plans panel in the CLI dashboard is disabled until plan-mode event capture is reliably working end-to-end. Plan nodes in the mind map remain active.\n- `DashboardState` now delegates to shared `EventAggregator` instead of maintaining its own aggregation logic\n\n## [0.12.2] - 2026-02-23\n\n### Added\n\n- **Update notifications**: The dashboard now checks the npm registry for newer versions on startup and shows a yellow banner in the status bar when an update is available (e.g., `v0.13.0 available \u2014 npm i -g sidekick-agent-hub`). Results are cached for 24 hours to avoid repeated network requests.\n\n## [0.12.1] - 2026-02-23\n\n### Fixed\n\n- **VS Code integration**: Fixed exit code 127 when the extension launches the CLI dashboard on systems using nvm or volta (node binary not found when shell init is bypassed)\n\n## [0.12.0] - 2026-02-22\n\n### Added\n\n- **"Open CLI Dashboard" VS Code Integration**: New VS Code command `Sidekick: Open CLI Dashboard` launches the TUI dashboard in an integrated terminal\n - Install the CLI with `npm install -g sidekick-agent-hub`\n\n## [0.11.0] - 2026-02-19\n\n### Added\n\n- **Initial Release**: Full-screen TUI dashboard for monitoring agent sessions from the terminal\n - Ink-based terminal UI with panels for sessions, tasks, kanban, mind map, notes, decisions, search, files, and git diff\n - Multi-provider support: auto-detects Claude Code, OpenCode, and Codex sessions\n - Reads from `~/.config/sidekick/` \u2014 the same data files the VS Code extension writes\n - Usage: `sidekick dashboard [--project <path>] [--provider <id>]`\n';
|
|
60217
|
+
CHANGELOG_default = '# Changelog\n\nAll notable changes to the Sidekick Agent Hub CLI will be documented in this file.\n\nThe format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),\nand this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n\n## [0.13.1] - 2026-03-04\n\n### Added\n\n- **`sidekick quota` Command**: One-shot subscription quota check showing 5-hour and 7-day utilization with color-coded progress bars and reset countdowns \u2014 supports `--json` for machine-readable output\n- **Quota Projections**: Elapsed-time projections shown in `sidekick quota` output and TUI dashboard quota section \u2014 displays projected end-of-window utilization next to current value (e.g., `40% \u2192 100%`), included in `--json` output as `projectedFiveHour` / `projectedSevenDay`\n\n## [0.13.0] - 2026-03-03\n\n_No CLI-specific changes in this release._\n\n## [0.12.10] - 2026-03-01\n\n### Added\n\n- **Events Panel** (key 7): Scrollable live event stream with colored type badges (`[USR]`, `[AST]`, `[TOOL]`, `[RES]`), timestamps, and keyword-highlighted summaries; detail tabs for full event JSON and surrounding context\n- **Charts Panel** (key 8): Tool frequency horizontal bars, event type distribution, 60-minute activity heatmap using `\u2591\u2592\u2593\u2588` intensity characters, and pattern analysis with frequency bars and template text\n- **Multi-Mode Filter**: `/` filter overlay now supports four modes \u2014 substring, fuzzy, regex, and date range \u2014 Tab cycles modes, regex mode shows red validation errors\n- **Search Term Highlighting**: Active filter terms highlighted in blue within side list items\n- **Timeline Keyword Coloring**: Event summaries in the Sessions panel Timeline tab now use semantic keyword coloring \u2014 errors red, success green, tool names cyan, file paths magenta\n\n### Removed\n\n- **Search Panel**: Removed redundant Search panel (previously key 7) \u2014 the `/` filter with multi-mode support serves the same purpose\n\n## [0.12.9] - 2026-02-28\n\n### Added\n\n- **Standalone Data Commands**: `sidekick tasks`, `sidekick decisions`, `sidekick notes`, `sidekick stats`, `sidekick handoff` for accessing project data without launching the TUI\n- **`sidekick search <query>`**: Cross-session full-text search from the terminal\n- **`sidekick context`**: Composite output of tasks, decisions, notes, and handoff for piping into other tools\n- **`--list` flag on `sidekick dump`**: Discover available session IDs before requiring `--session <id>`\n- **Search Panel**: Search panel (panel 7) wired into the TUI dashboard\n\n### Changed\n\n- **`taskMerger` utility**: Duplicate `mergeTasks` logic extracted into shared `taskMerger` utility\n- **Model constants**: Hardcoded model IDs extracted to named constants\n\n### Fixed\n\n- **`convention` icon**: Notes panel icon replaced with valid `tip` type\n- **Linux clipboard**: Now supports Wayland (`wl-copy`) and `xsel` fallbacks, with error messages instead of silent failure\n- **`provider.dispose()`**: Added to `dump` and `report` commands (prevents SQLite connection leaks)\n\n## [0.12.8] - 2026-02-28\n\n### Changed\n\n- **Dashboard UI/UX Polish**: Visual overhaul for better hierarchy, consistency, and readability\n - Splash screen and help overlay now display the robot ASCII logo\n - Toast notifications show severity icons (\u2718 error, \u26A0 warning, \u25CF info) with inner padding\n - Focused pane uses double-border for clear focus indication\n - Section dividers (`\u2500\u2500 Title \u2500\u2500\u2500\u2500`) replace bare bold headers in summary, agents, and context attribution\n - Tab bar: active tab underlined in magenta, inactive tabs dimmed, bracket syntax removed\n - Status bar: segmented layout with `\u2502` separators; keys bold, labels dim\n - Summary metrics condensed: elapsed/events/compactions on one line, tokens on one line with cache rate and cost\n - Sparklines display peak metadata annotations\n - Progress bars use blessed color tags for consistent coloring\n - Help overlay uses dot-leader alignment for all keybinding rows\n - Empty state hints per panel (e.g. "Tasks appear as your agent works.")\n - Session picker groups sessions by provider with section headers when multiple providers are present\n\n## [0.12.7] - 2026-02-27\n\n### Added\n\n- **HTML Session Report**: `sidekick report` command generates a self-contained HTML report and opens it in the default browser\n - Options: `--session`, `--output`, `--theme` (dark/light), `--no-open`, `--no-thinking`\n - TUI Dashboard: press `r` to generate and open an HTML report for the current session\n\n## [0.12.6] - 2026-02-26\n\n### Added\n\n- **Session Dump Command**: `sidekick dump` exports session data in text, markdown, or JSON format with `--format`, `--width`, and `--expand` options\n- **Plans Panel Re-enabled**: Plans panel restored in CLI dashboard with plan file discovery from `~/.claude/plans/`\n- **Enhanced Status Bar**: Session info display improved with richer metadata\n\n### Fixed\n\n- **Old snapshot format migration**: Restoring pre-0.12.3 session snapshots no longer shows empty timeline entries\n\n### Changed\n\n- **Phrase library moved to shared**: CLI-specific phrase formatting kept local, all phrase content now from `sidekick-shared`\n\n## [0.12.5] - 2026-02-24\n\n### Fixed\n\n- **Update check too slow to notice new versions**: Reduced npm registry cache TTL from 24 hours to 4 hours so upgrade notices appear sooner after a new release\n\n## [0.12.4] - 2026-02-24\n\n### Fixed\n\n- **Session crash on upgrade**: Fixed `d.timestamp.getTime is not a function` error when restoring tool call data from session snapshots \u2014 `Date` objects were serialized to strings by JSON but not rehydrated on restore, causing the session monitor to crash on first run after upgrading from 0.12.2 to 0.12.3\n\n## [0.12.3] - 2026-02-24\n\n### Added\n\n- **Latest-node indicator**: The most recently added node in tree and boxed mind map views is now marked with a yellow indicator\n- **Plan analytics in mind map**: Tree and boxed views now display plan progress and per-step metrics\n - Tree view: plan header shows completion stats; steps show complexity, duration, tokens, tool calls, and errors in metadata brackets\n - Box view: progress bar with completion percentage; steps show right-aligned metrics; subtitle shows step count and total duration\n- **Cross-provider plan extraction**: Shared `PlanExtractor` now handles Claude Code (EnterPlanMode/ExitPlanMode) and OpenCode (`<proposed_plan>` XML) plans \u2014 previously only Codex plans were shown\n- **Enriched plan data model**: Plan steps include duration, token count, tool call count, and error messages\n- **Phase-grouped plan display**: When a plan has phase structure, tree and boxed views group steps under phase headers with context lines from the original plan markdown\n- **Node type filter**: Press `f` on the Mind Map tab to cycle through node type filters (file, tool, task, subagent, command, plan, knowledge-note) \u2014 non-matching sections render dimmed in grey\n\n### Fixed\n\n- **Kanban board regression**: Subagent and plan-step tasks now correctly appear in the kanban board\n\n### Changed\n\n- **Plans panel temporarily disabled**: The Plans panel in the CLI dashboard is disabled until plan-mode event capture is reliably working end-to-end. Plan nodes in the mind map remain active.\n- `DashboardState` now delegates to shared `EventAggregator` instead of maintaining its own aggregation logic\n\n## [0.12.2] - 2026-02-23\n\n### Added\n\n- **Update notifications**: The dashboard now checks the npm registry for newer versions on startup and shows a yellow banner in the status bar when an update is available (e.g., `v0.13.0 available \u2014 npm i -g sidekick-agent-hub`). Results are cached for 24 hours to avoid repeated network requests.\n\n## [0.12.1] - 2026-02-23\n\n### Fixed\n\n- **VS Code integration**: Fixed exit code 127 when the extension launches the CLI dashboard on systems using nvm or volta (node binary not found when shell init is bypassed)\n\n## [0.12.0] - 2026-02-22\n\n### Added\n\n- **"Open CLI Dashboard" VS Code Integration**: New VS Code command `Sidekick: Open CLI Dashboard` launches the TUI dashboard in an integrated terminal\n - Install the CLI with `npm install -g sidekick-agent-hub`\n\n## [0.11.0] - 2026-02-19\n\n### Added\n\n- **Initial Release**: Full-screen TUI dashboard for monitoring agent sessions from the terminal\n - Ink-based terminal UI with panels for sessions, tasks, kanban, mind map, notes, decisions, search, files, and git diff\n - Multi-provider support: auto-detects Claude Code, OpenCode, and Codex sessions\n - Reads from `~/.config/sidekick/` \u2014 the same data files the VS Code extension writes\n - Usage: `sidekick dashboard [--project <path>] [--provider <id>]`\n';
|
|
60188
60218
|
}
|
|
60189
60219
|
});
|
|
60190
60220
|
|
|
@@ -62183,6 +62213,92 @@ var init_stats = __esm({
|
|
|
62183
62213
|
}
|
|
62184
62214
|
});
|
|
62185
62215
|
|
|
62216
|
+
// src/commands/quota.ts
|
|
62217
|
+
var quota_exports = {};
|
|
62218
|
+
__export(quota_exports, {
|
|
62219
|
+
formatTimeUntil: () => formatTimeUntil,
|
|
62220
|
+
getUtilizationColor: () => getUtilizationColor2,
|
|
62221
|
+
makeChalkBar: () => makeChalkBar,
|
|
62222
|
+
quotaAction: () => quotaAction
|
|
62223
|
+
});
|
|
62224
|
+
function getUtilizationColor2(percent) {
|
|
62225
|
+
if (percent < 60) return source_default.green;
|
|
62226
|
+
if (percent < 80) return source_default.yellow;
|
|
62227
|
+
return source_default.red;
|
|
62228
|
+
}
|
|
62229
|
+
function makeChalkBar(percent, width) {
|
|
62230
|
+
const filled = Math.round(percent / 100 * width);
|
|
62231
|
+
const empty = width - filled;
|
|
62232
|
+
const color = getUtilizationColor2(percent);
|
|
62233
|
+
return color("\u2588".repeat(filled)) + source_default.dim("\u2591".repeat(empty));
|
|
62234
|
+
}
|
|
62235
|
+
function formatTimeUntil(isoString) {
|
|
62236
|
+
if (!isoString) return "";
|
|
62237
|
+
const ms = new Date(isoString).getTime() - Date.now();
|
|
62238
|
+
if (ms <= 0) return "now";
|
|
62239
|
+
const totalMinutes = Math.floor(ms / 6e4);
|
|
62240
|
+
const days = Math.floor(totalMinutes / 1440);
|
|
62241
|
+
const hours = Math.floor(totalMinutes % 1440 / 60);
|
|
62242
|
+
const minutes = totalMinutes % 60;
|
|
62243
|
+
const parts = [];
|
|
62244
|
+
if (days > 0) parts.push(`${days}d`);
|
|
62245
|
+
if (hours > 0) parts.push(`${hours}h`);
|
|
62246
|
+
if (minutes > 0 && days === 0) parts.push(`${minutes}m`);
|
|
62247
|
+
return "in " + (parts.join(" ") || "0m");
|
|
62248
|
+
}
|
|
62249
|
+
async function quotaAction(_opts, cmd) {
|
|
62250
|
+
const globalOpts = cmd.parent.opts();
|
|
62251
|
+
const jsonOutput = !!globalOpts.json;
|
|
62252
|
+
const service = new QuotaService();
|
|
62253
|
+
const quota = await service.fetchOnce();
|
|
62254
|
+
if (!quota.available) {
|
|
62255
|
+
if (jsonOutput) {
|
|
62256
|
+
process.stdout.write(JSON.stringify(quota, null, 2) + "\n");
|
|
62257
|
+
return;
|
|
62258
|
+
}
|
|
62259
|
+
let msg;
|
|
62260
|
+
switch (quota.error) {
|
|
62261
|
+
case "no-credentials":
|
|
62262
|
+
msg = "No Claude Code credentials found. Sign in with `claude` first.";
|
|
62263
|
+
break;
|
|
62264
|
+
case "auth-failed":
|
|
62265
|
+
msg = "Authentication failed. Try signing in to Claude Code again.";
|
|
62266
|
+
break;
|
|
62267
|
+
case "network-error":
|
|
62268
|
+
msg = "Could not reach the Anthropic API. Check your connection.";
|
|
62269
|
+
break;
|
|
62270
|
+
default:
|
|
62271
|
+
msg = quota.error ?? "Unknown error fetching quota.";
|
|
62272
|
+
}
|
|
62273
|
+
process.stderr.write(source_default.red(msg) + "\n");
|
|
62274
|
+
process.exit(1);
|
|
62275
|
+
}
|
|
62276
|
+
if (jsonOutput) {
|
|
62277
|
+
process.stdout.write(JSON.stringify(quota, null, 2) + "\n");
|
|
62278
|
+
return;
|
|
62279
|
+
}
|
|
62280
|
+
const barWidth = 30;
|
|
62281
|
+
const fivePct = Math.round(quota.fiveHour.utilization);
|
|
62282
|
+
const sevenPct = Math.round(quota.sevenDay.utilization);
|
|
62283
|
+
const fiveReset = formatTimeUntil(quota.fiveHour.resetsAt);
|
|
62284
|
+
const sevenReset = formatTimeUntil(quota.sevenDay.resetsAt);
|
|
62285
|
+
const fiveProj = quota.projectedFiveHour != null ? ` ${source_default.dim("\u2192")} ${getUtilizationColor2(quota.projectedFiveHour)(String(Math.round(quota.projectedFiveHour)).padStart(3) + "%")}` : "";
|
|
62286
|
+
const sevenProj = quota.projectedSevenDay != null ? ` ${source_default.dim("\u2192")} ${getUtilizationColor2(quota.projectedSevenDay)(String(Math.round(quota.projectedSevenDay)).padStart(3) + "%")}` : "";
|
|
62287
|
+
process.stdout.write(source_default.bold("Subscription Quota\n"));
|
|
62288
|
+
process.stdout.write(source_default.dim("\u2500".repeat(50) + "\n"));
|
|
62289
|
+
process.stdout.write(` ${source_default.dim("5-Hour")} ${makeChalkBar(fivePct, barWidth)} ${String(fivePct).padStart(3)}%${fiveProj} ${source_default.dim("resets " + fiveReset)}
|
|
62290
|
+
`);
|
|
62291
|
+
process.stdout.write(` ${source_default.dim("7-Day")} ${makeChalkBar(sevenPct, barWidth)} ${String(sevenPct).padStart(3)}%${sevenProj} ${source_default.dim("resets " + sevenReset)}
|
|
62292
|
+
`);
|
|
62293
|
+
}
|
|
62294
|
+
var init_quota = __esm({
|
|
62295
|
+
"src/commands/quota.ts"() {
|
|
62296
|
+
"use strict";
|
|
62297
|
+
init_source();
|
|
62298
|
+
init_QuotaService();
|
|
62299
|
+
}
|
|
62300
|
+
});
|
|
62301
|
+
|
|
62186
62302
|
// src/commands/handoff.ts
|
|
62187
62303
|
var handoff_exports = {};
|
|
62188
62304
|
__export(handoff_exports, {
|
|
@@ -62246,14 +62362,14 @@ function resolveProvider(opts) {
|
|
|
62246
62362
|
return new import_sidekick_shared23.ClaudeCodeProvider();
|
|
62247
62363
|
}
|
|
62248
62364
|
}
|
|
62249
|
-
var import_sidekick_shared22, import_sidekick_shared23, program2, dashCmd, dumpCmd, ctxCmd, reportCmd, searchCmd, tasksCmd, decisionsCmd, notesCmd, statsCmd, handoffCmd;
|
|
62365
|
+
var import_sidekick_shared22, import_sidekick_shared23, program2, dashCmd, dumpCmd, ctxCmd, reportCmd, searchCmd, tasksCmd, decisionsCmd, notesCmd, statsCmd, quotaCmd, handoffCmd;
|
|
62250
62366
|
var init_cli = __esm({
|
|
62251
62367
|
"src/cli.ts"() {
|
|
62252
62368
|
init_esm();
|
|
62253
62369
|
import_sidekick_shared22 = __toESM(require_dist(), 1);
|
|
62254
62370
|
import_sidekick_shared23 = __toESM(require_dist(), 1);
|
|
62255
62371
|
program2 = new Command();
|
|
62256
|
-
program2.name("sidekick").description("Query Sidekick project intelligence from the command line").version("0.
|
|
62372
|
+
program2.name("sidekick").description("Query Sidekick project intelligence from the command line").version("0.13.1").option("--json", "Output as JSON").option("--project <path>", "Override project path (default: cwd)").option("--provider <id>", "Provider: claude-code, opencode, codex, auto (default: auto)");
|
|
62257
62373
|
dashCmd = new Command("dashboard").description("Full-screen TUI dashboard with live session metrics").option("--session <id>", "Follow a specific session (default: most recent)").option("--replay", "Replay existing events before streaming new ones").action(async (_opts, cmd) => {
|
|
62258
62374
|
const { dashboardAction: dashboardAction2 } = await init_dashboard().then(() => dashboard_exports);
|
|
62259
62375
|
return dashboardAction2(_opts, cmd);
|
|
@@ -62300,6 +62416,11 @@ var init_cli = __esm({
|
|
|
62300
62416
|
return statsAction2(_opts, cmd);
|
|
62301
62417
|
});
|
|
62302
62418
|
program2.addCommand(statsCmd);
|
|
62419
|
+
quotaCmd = new Command("quota").description("Show subscription quota utilization (Claude Max / Claude Code)").action(async (_opts, cmd) => {
|
|
62420
|
+
const { quotaAction: quotaAction2 } = await Promise.resolve().then(() => (init_quota(), quota_exports));
|
|
62421
|
+
return quotaAction2(_opts, cmd);
|
|
62422
|
+
});
|
|
62423
|
+
program2.addCommand(quotaCmd);
|
|
62303
62424
|
handoffCmd = new Command("handoff").description("Show the latest session handoff document for the current project").action(async (_opts, cmd) => {
|
|
62304
62425
|
const { handoffAction: handoffAction2 } = await Promise.resolve().then(() => (init_handoff(), handoff_exports));
|
|
62305
62426
|
return handoffAction2(_opts, cmd);
|