sidekick-agent-hub 0.13.7 → 0.13.8

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 CHANGED
@@ -110,7 +110,9 @@ Subscription Quota
110
110
  7-Day ██████████████████████░░░░░░░░ 72% resets in 4d 6h
111
111
  ```
112
112
 
113
- Use `--json` for machine-readable output. Requires Claude Code credentials (`~/.claude/.credentials.json`).
113
+ When quota data is unavailable, `sidekick quota` shows structured auth, rate-limit, network, server, or unexpected-failure messaging instead of a generic raw error. The dashboard Sessions panel also keeps a compact inline quota state for Claude Code instead of hiding quota entirely.
114
+
115
+ Use `--json` for machine-readable output. Requires Claude Code credentials (`~/.claude/.credentials.json`). JSON output includes `failureKind`, `httpStatus`, and `retryAfterMs` on unavailable responses.
114
116
 
115
117
  ## Dashboard Panels
116
118
 
@@ -16796,14 +16796,27 @@ var require_quota = __commonJS({
16796
16796
  return void 0;
16797
16797
  return Math.min(Math.round(utilization * (windowMs / elapsed)), 200);
16798
16798
  }
16799
- function unavailableState(error) {
16799
+ function unavailableState(error, meta = {}) {
16800
16800
  return {
16801
16801
  fiveHour: { utilization: 0, resetsAt: "" },
16802
16802
  sevenDay: { utilization: 0, resetsAt: "" },
16803
16803
  available: false,
16804
- error
16804
+ error,
16805
+ ...meta
16805
16806
  };
16806
16807
  }
16808
+ function parseRetryAfterMs(retryAfter) {
16809
+ if (!retryAfter)
16810
+ return void 0;
16811
+ const seconds = Number(retryAfter);
16812
+ if (Number.isFinite(seconds) && seconds >= 0) {
16813
+ return Math.round(seconds * 1e3);
16814
+ }
16815
+ const retryAt = Date.parse(retryAfter);
16816
+ if (Number.isNaN(retryAt))
16817
+ return void 0;
16818
+ return Math.max(retryAt - Date.now(), 0);
16819
+ }
16807
16820
  async function fetchQuota2(accessToken) {
16808
16821
  try {
16809
16822
  const res = await fetch(USAGE_URL, {
@@ -16815,9 +16828,29 @@ var require_quota = __commonJS({
16815
16828
  }
16816
16829
  });
16817
16830
  if (!res.ok) {
16818
- if (res.status === 401)
16819
- return unavailableState("Sign in to Claude Code to view quota");
16820
- return unavailableState(`API error: ${res.status}`);
16831
+ if (res.status === 401) {
16832
+ return unavailableState("Sign in to Claude Code to view quota", {
16833
+ failureKind: "auth",
16834
+ httpStatus: res.status
16835
+ });
16836
+ }
16837
+ if (res.status === 429) {
16838
+ return unavailableState(`API error: ${res.status}`, {
16839
+ failureKind: "rate_limit",
16840
+ httpStatus: res.status,
16841
+ retryAfterMs: parseRetryAfterMs(res.headers.get("retry-after"))
16842
+ });
16843
+ }
16844
+ if (res.status >= 500 && res.status <= 599) {
16845
+ return unavailableState(`API error: ${res.status}`, {
16846
+ failureKind: "server",
16847
+ httpStatus: res.status
16848
+ });
16849
+ }
16850
+ return unavailableState(`API error: ${res.status}`, {
16851
+ failureKind: "unknown",
16852
+ httpStatus: res.status
16853
+ });
16821
16854
  }
16822
16855
  const data = await res.json();
16823
16856
  const fiveUtil = data.five_hour?.utilization ?? 0;
@@ -16832,7 +16865,95 @@ var require_quota = __commonJS({
16832
16865
  projectedSevenDay: projectFromElapsed(sevenUtil, sevenResetsAt, SEVEN_DAY_MS)
16833
16866
  };
16834
16867
  } catch {
16835
- return unavailableState("Network error");
16868
+ return unavailableState("Network error", { failureKind: "network" });
16869
+ }
16870
+ }
16871
+ }
16872
+ });
16873
+
16874
+ // ../sidekick-shared/dist/quotaPresentation.js
16875
+ var require_quotaPresentation = __commonJS({
16876
+ "../sidekick-shared/dist/quotaPresentation.js"(exports) {
16877
+ "use strict";
16878
+ Object.defineProperty(exports, "__esModule", { value: true });
16879
+ exports.describeQuotaFailure = describeQuotaFailure4;
16880
+ function formatRetryAfter(ms) {
16881
+ if (ms <= 0)
16882
+ return "now";
16883
+ const totalSeconds = Math.ceil(ms / 1e3);
16884
+ const days = Math.floor(totalSeconds / 86400);
16885
+ const hours = Math.floor(totalSeconds % 86400 / 3600);
16886
+ const minutes = Math.floor(totalSeconds % 3600 / 60);
16887
+ const seconds = totalSeconds % 60;
16888
+ const parts = [];
16889
+ if (days > 0)
16890
+ parts.push(`${days}d`);
16891
+ if (hours > 0)
16892
+ parts.push(`${hours}h`);
16893
+ if (minutes > 0 && days === 0)
16894
+ parts.push(`${minutes}m`);
16895
+ if (parts.length === 0)
16896
+ parts.push(`${seconds}s`);
16897
+ return parts.join(" ");
16898
+ }
16899
+ function describeQuotaFailure4(quota) {
16900
+ if (!quota || quota.available || !quota.failureKind)
16901
+ return null;
16902
+ switch (quota.failureKind) {
16903
+ case "auth":
16904
+ if (quota.error === "No OAuth token available") {
16905
+ return {
16906
+ severity: "error",
16907
+ title: "Sign in required",
16908
+ message: "No Claude Code credentials are available in this environment.",
16909
+ detail: "Run `claude` to sign in, then retry quota refresh.",
16910
+ alertKey: "auth:no-credentials",
16911
+ isRetryable: false
16912
+ };
16913
+ }
16914
+ return {
16915
+ severity: "error",
16916
+ title: "Claude Code sign-in expired",
16917
+ message: "The current Claude Code OAuth session was rejected.",
16918
+ detail: "Sign in again to refresh subscription quota.",
16919
+ alertKey: `auth:${quota.httpStatus ?? "unknown"}`,
16920
+ isRetryable: false
16921
+ };
16922
+ case "network":
16923
+ return {
16924
+ severity: "warning",
16925
+ title: "Quota API unreachable",
16926
+ message: "Could not reach Anthropic from the current environment.",
16927
+ detail: "Check connectivity, proxy, or firewall settings, then retry.",
16928
+ alertKey: "network",
16929
+ isRetryable: true
16930
+ };
16931
+ case "rate_limit":
16932
+ return {
16933
+ severity: "warning",
16934
+ title: "Quota API rate limited",
16935
+ message: quota.retryAfterMs != null ? `Retry in ${formatRetryAfter(quota.retryAfterMs)}.` : "Retry shortly.",
16936
+ detail: quota.httpStatus != null ? `Anthropic returned HTTP ${quota.httpStatus}.` : void 0,
16937
+ alertKey: `rate_limit:${quota.httpStatus ?? 429}`,
16938
+ isRetryable: true
16939
+ };
16940
+ case "server":
16941
+ return {
16942
+ severity: "warning",
16943
+ title: "Quota API unavailable",
16944
+ message: quota.httpStatus != null ? `Anthropic returned HTTP ${quota.httpStatus}. Try again shortly.` : "Anthropic quota data is temporarily unavailable.",
16945
+ alertKey: `server:${quota.httpStatus ?? "unknown"}`,
16946
+ isRetryable: true
16947
+ };
16948
+ case "unknown":
16949
+ return {
16950
+ severity: "error",
16951
+ title: "Unexpected quota response",
16952
+ message: quota.httpStatus != null ? `Anthropic returned HTTP ${quota.httpStatus}.` : quota.error ?? "Quota data could not be retrieved.",
16953
+ detail: "This failure is not classified as retryable.",
16954
+ alertKey: `unknown:${quota.httpStatus ?? "none"}`,
16955
+ isRetryable: false
16956
+ };
16836
16957
  }
16837
16958
  }
16838
16959
  }
@@ -16895,7 +17016,7 @@ var require_dist = __commonJS({
16895
17016
  Object.defineProperty(exports, "__esModule", { value: true });
16896
17017
  exports.findActiveClaudeSession = exports.discoverSessionDirectory = exports.getClaudeSessionDirectory = exports.encodeClaudeWorkspacePath = exports.detectSessionActivity = exports.extractTaskInfo = exports.scanSubagentDir = exports.normalizeCodexToolInput = exports.normalizeCodexToolName = exports.extractPatchFilePaths = exports.CodexRolloutParser = exports.parseDbPartData = exports.parseDbMessageData = exports.convertOpenCodeMessage = exports.detectPlanModeFromText = exports.normalizeToolInput = exports.normalizeToolName = exports.TRUNCATION_PATTERNS = exports.JsonlParser = exports.CodexProvider = exports.OpenCodeProvider = exports.ClaudeCodeProvider = exports.getAllDetectedProviders = exports.detectProvider = exports.readClaudeCodePlanFiles = exports.getPlanAnalytics = exports.writePlans = exports.getLatestPlan = exports.readPlans = exports.readLatestHandoff = exports.readHistory = exports.readNotes = exports.readDecisions = exports.readTasks = exports.getProjectSlugRaw = exports.getProjectSlug = exports.encodeWorkspacePath = exports.getGlobalDataPath = exports.getProjectDataPath = exports.getConfigDir = exports.MAX_PLANS_PER_PROJECT = exports.PLAN_SCHEMA_VERSION = exports.createEmptyTokenTotals = exports.HISTORICAL_DATA_SCHEMA_VERSION = exports.STALENESS_THRESHOLDS = exports.IMPORTANCE_DECAY_FACTORS = exports.KNOWLEDGE_NOTE_SCHEMA_VERSION = exports.DECISION_LOG_SCHEMA_VERSION = exports.normalizeTaskStatus = exports.TASK_PERSISTENCE_SCHEMA_VERSION = void 0;
16897
17018
  exports.HeatmapTracker = exports.FrequencyTracker = exports.getSnapshotPath = exports.isSnapshotValid = exports.deleteSnapshot = exports.loadSnapshot = exports.saveSnapshot = exports.parseTodoDependencies = exports.EventAggregator = exports.getRandomPhrase = exports.ALL_PHRASES = exports.HIGHLIGHT_CSS = exports.clearHighlightCache = exports.highlightEvent = exports.formatSessionJson = exports.formatSessionMarkdown = exports.formatSessionText = exports.classifyNoise = exports.shouldMergeWithPrevious = exports.classifyFollowEvent = exports.classifyMessage = exports.getSoftNoiseReason = exports.isHardNoiseFollowEvent = exports.isHardNoise = exports.formatToolSummary = exports.toFollowEvents = exports.createWatcher = exports.parseChangelog = exports.extractProposedPlanShared = exports.parsePlanMarkdownShared = exports.PlanExtractor = exports.composeContext = exports.FilterEngine = exports.searchSessions = exports.CodexDatabase = exports.OpenCodeDatabase = exports.discoverDebugLogs = exports.collapseDuplicates = exports.filterByLevel = exports.parseDebugLog = exports.scanSubagentTraces = exports.findAllSessionsWithWorktrees = exports.discoverWorktreeSiblings = exports.resolveWorktreeMainRepo = exports.getAllClaudeProjectFolders = exports.decodeEncodedPath = exports.getMostRecentlyActiveSessionDir = exports.findSubdirectorySessionDirs = exports.findSessionsInDirectory = exports.findAllClaudeSessions = void 0;
16898
- exports.fetchProviderStatus = exports.fetchQuota = exports.readClaudeMaxAccessTokenSync = exports.readClaudeMaxCredentials = exports.openInBrowser = exports.parseTranscript = exports.generateHtmlReport = exports.PatternExtractor = void 0;
17019
+ exports.fetchProviderStatus = exports.describeQuotaFailure = exports.fetchQuota = exports.readClaudeMaxAccessTokenSync = exports.readClaudeMaxCredentials = exports.openInBrowser = exports.parseTranscript = exports.generateHtmlReport = exports.PatternExtractor = void 0;
16899
17020
  var taskPersistence_1 = require_taskPersistence();
16900
17021
  Object.defineProperty(exports, "TASK_PERSISTENCE_SCHEMA_VERSION", { enumerable: true, get: function() {
16901
17022
  return taskPersistence_1.TASK_PERSISTENCE_SCHEMA_VERSION;
@@ -17263,6 +17384,10 @@ var require_dist = __commonJS({
17263
17384
  Object.defineProperty(exports, "fetchQuota", { enumerable: true, get: function() {
17264
17385
  return quota_1.fetchQuota;
17265
17386
  } });
17387
+ var quotaPresentation_1 = require_quotaPresentation();
17388
+ Object.defineProperty(exports, "describeQuotaFailure", { enumerable: true, get: function() {
17389
+ return quotaPresentation_1.describeQuotaFailure;
17390
+ } });
17266
17391
  var providerStatus_1 = require_providerStatus();
17267
17392
  Object.defineProperty(exports, "fetchProviderStatus", { enumerable: true, get: function() {
17268
17393
  return providerStatus_1.fetchProviderStatus;
@@ -19332,12 +19457,25 @@ var init_StaticDataLoader = __esm({
19332
19457
  });
19333
19458
 
19334
19459
  // src/dashboard/QuotaService.ts
19335
- var import_sidekick_shared4, REFRESH_MS, QuotaService;
19460
+ function unavailableAuthState() {
19461
+ return {
19462
+ fiveHour: { utilization: 0, resetsAt: "" },
19463
+ sevenDay: { utilization: 0, resetsAt: "" },
19464
+ available: false,
19465
+ error: NO_CREDENTIALS_ERROR,
19466
+ failureKind: "auth"
19467
+ };
19468
+ }
19469
+ function shouldKeepCachedQuota(state) {
19470
+ return !state.available && (state.failureKind === "network" || state.failureKind === "rate_limit" || state.failureKind === "server");
19471
+ }
19472
+ var import_sidekick_shared4, REFRESH_MS, NO_CREDENTIALS_ERROR, QuotaService;
19336
19473
  var init_QuotaService = __esm({
19337
19474
  "src/dashboard/QuotaService.ts"() {
19338
19475
  "use strict";
19339
19476
  import_sidekick_shared4 = __toESM(require_dist(), 1);
19340
19477
  REFRESH_MS = 3e4;
19478
+ NO_CREDENTIALS_ERROR = "No OAuth token available";
19341
19479
  QuotaService = class {
19342
19480
  _interval = null;
19343
19481
  _cached = null;
@@ -19367,18 +19505,18 @@ var init_QuotaService = __esm({
19367
19505
  async fetchOnce() {
19368
19506
  const creds = await (0, import_sidekick_shared4.readClaudeMaxCredentials)();
19369
19507
  if (!creds) {
19370
- return { fiveHour: { utilization: 0, resetsAt: "" }, sevenDay: { utilization: 0, resetsAt: "" }, available: false, error: "no-credentials" };
19508
+ return unavailableAuthState();
19371
19509
  }
19372
19510
  return (0, import_sidekick_shared4.fetchQuota)(creds.accessToken);
19373
19511
  }
19374
19512
  async fetchQuota() {
19375
19513
  const creds = await (0, import_sidekick_shared4.readClaudeMaxCredentials)();
19376
19514
  if (!creds) {
19377
- this.emit({ fiveHour: { utilization: 0, resetsAt: "" }, sevenDay: { utilization: 0, resetsAt: "" }, available: false });
19515
+ this.emit(unavailableAuthState());
19378
19516
  return;
19379
19517
  }
19380
19518
  const state = await (0, import_sidekick_shared4.fetchQuota)(creds.accessToken);
19381
- if (!state.available && this._cached?.available) return;
19519
+ if (shouldKeepCachedQuota(state) && this._cached?.available) return;
19382
19520
  this.emit(state);
19383
19521
  }
19384
19522
  emit(state) {
@@ -19465,7 +19603,7 @@ var init_UpdateCheckService = __esm({
19465
19603
  /** Run the update check (one-shot). */
19466
19604
  async check() {
19467
19605
  try {
19468
- const current = "0.13.7";
19606
+ const current = "0.13.8";
19469
19607
  const cached = this.readCache();
19470
19608
  let latest;
19471
19609
  if (cached && Date.now() - cached.checkedAt < CACHE_TTL_MS) {
@@ -21048,6 +21186,18 @@ ${hint}{/grey-fg}`;
21048
21186
  return ` {grey-fg}\u2192{/grey-fg} {${pc}-fg}${q.projectedSevenDay.toFixed(0)}%{/${pc}-fg}`;
21049
21187
  })() : "";
21050
21188
  lines.push(` {grey-fg}7d{/grey-fg} ${sevenBar} {bold}${q.sevenDay.utilization.toFixed(0)}%{/bold}${sevenProj}`);
21189
+ } else if (m.providerId === "claude-code" && m.quota) {
21190
+ const descriptor = (0, import_sidekick_shared7.describeQuotaFailure)(m.quota);
21191
+ if (descriptor) {
21192
+ const severityColor = descriptor.severity === "warning" ? "yellow" : descriptor.severity === "info" ? "cyan" : "red";
21193
+ lines.push("", sectionHeader("Quota", w2));
21194
+ lines.push(` {${severityColor}-fg}${descriptor.title}{/${severityColor}-fg}`);
21195
+ const failureText = [descriptor.message, descriptor.detail].filter(Boolean).join(" ");
21196
+ const quotaTextWidth = Math.max(20, detailWidth(w2) - 4);
21197
+ for (const line of wordWrap(failureText, quotaTextWidth)) {
21198
+ lines.push(` {grey-fg}${line}{/grey-fg}`);
21199
+ }
21200
+ }
21051
21201
  }
21052
21202
  if (m.providerStatus && m.providerStatus.indicator !== "none") {
21053
21203
  const ps = m.providerStatus;
@@ -60054,7 +60204,7 @@ function StatusBar({
60054
60204
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: parseBlessedTags(BRAND_INLINE) }),
60055
60205
  /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { dimColor: true, children: [
60056
60206
  " v",
60057
- "0.13.7"
60207
+ "0.13.8"
60058
60208
  ] }),
60059
60209
  updateInfo && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { color: "yellow", children: [
60060
60210
  " (v",
@@ -60432,7 +60582,7 @@ function ChangelogOverlay({ entries, scrollOffset }) {
60432
60582
  " ",
60433
60583
  /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Text, { bold: true, color: "cyan", children: [
60434
60584
  "Terminal Dashboard v",
60435
- "0.13.7"
60585
+ "0.13.8"
60436
60586
  ] }),
60437
60587
  latestDate ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Text, { color: "gray", children: [
60438
60588
  " \u2014 ",
@@ -60754,7 +60904,7 @@ var init_mouse = __esm({
60754
60904
  var CHANGELOG_default;
60755
60905
  var init_CHANGELOG = __esm({
60756
60906
  "CHANGELOG.md"() {
60757
- 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.7] - 2026-03-11\n\n### Changed\n\n- **npm README sync**: Updated the published CLI package README to reflect current OpenCode monitoring behavior, platform-specific data directories, and the `sqlite3` runtime requirement\n- **README badge cleanup**: Removed the Ask DeepWiki badge from the published CLI package README; the repo root README still keeps it\n\n## [0.13.6] - 2026-03-11\n\n### Changed\n\n- **Refreshed CLI Dashboard Wordmark**: Updated the dashboard wordmark/header styling for a cleaner splash and dashboard identity\n\n### Fixed\n\n- **OpenCode dashboard startup**: OpenCode DB-backed session discovery now resolves projects by worktree, sandboxes, and session directory instead of quietly behaving like no session exists\n- **OpenCode runtime notices**: The CLI now prints an OpenCode-only actionable notice when `opencode.db` exists but `sqlite3` is missing, blocked, or otherwise unusable in the current shell environment\n\n## [0.13.5] - 2026-03-10\n\n### Added\n\n- **`sidekick status` Command**: One-shot Claude API status check with color-coded text output and `--json` mode\n- **Dashboard Status Banner**: Status bar shows a colored `\u25CF API minor/major/critical` indicator when Claude is degraded; Sessions panel Summary tab shows an "API Status" section with affected components and active incident details. Polls every 60s\n\n## [0.13.4] - 2026-03-08\n\n### Fixed\n\n- **Onboarding Phrase Spam**: Splash screen and detail pane motivational phrases memoized \u2014 no longer flicker every render tick (fixes [#13](https://github.com/cesarandreslopez/sidekick-agent-hub/issues/13))\n\n### Changed\n\n- **Simplified Logo**: Replaced 6-line ASCII robot art with compact text header in splash, help, and changelog overlays\n- **Removed Dead Code**: Removed unused `getSplashContent()` and `HELP_HEADER` exports from branding module\n\n## [0.13.3] - 2026-03-04\n\n_No CLI-specific changes in this release._\n\n## [0.13.2] - 2026-03-04\n\n_No CLI-specific changes in this release._\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';
60907
+ 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.8] - 2026-03-12\n\n### Changed\n\n- **Structured quota failure output**: `sidekick quota` now renders consistent auth, rate-limit, server, network, and unexpected-failure copy from shared quota failure descriptors while preserving `--json` machine-readable output\n- **Dashboard unavailable quota rendering**: The Sessions panel now shows Claude Code quota failures inline instead of hiding the quota section whenever subscription data is unavailable\n- **Quota transition toasts**: The Ink dashboard now fires low-noise toast notifications only when Claude Code quota failure state changes, avoiding repeated alerts every polling interval\n\n## [0.13.7] - 2026-03-11\n\n### Changed\n\n- **npm README sync**: Updated the published CLI package README to reflect current OpenCode monitoring behavior, platform-specific data directories, and the `sqlite3` runtime requirement\n- **README badge cleanup**: Removed the Ask DeepWiki badge from the published CLI package README; the repo root README still keeps it\n\n## [0.13.6] - 2026-03-11\n\n### Changed\n\n- **Refreshed CLI Dashboard Wordmark**: Updated the dashboard wordmark/header styling for a cleaner splash and dashboard identity\n\n### Fixed\n\n- **OpenCode dashboard startup**: OpenCode DB-backed session discovery now resolves projects by worktree, sandboxes, and session directory instead of quietly behaving like no session exists\n- **OpenCode runtime notices**: The CLI now prints an OpenCode-only actionable notice when `opencode.db` exists but `sqlite3` is missing, blocked, or otherwise unusable in the current shell environment\n\n## [0.13.5] - 2026-03-10\n\n### Added\n\n- **`sidekick status` Command**: One-shot Claude API status check with color-coded text output and `--json` mode\n- **Dashboard Status Banner**: Status bar shows a colored `\u25CF API minor/major/critical` indicator when Claude is degraded; Sessions panel Summary tab shows an "API Status" section with affected components and active incident details. Polls every 60s\n\n## [0.13.4] - 2026-03-08\n\n### Fixed\n\n- **Onboarding Phrase Spam**: Splash screen and detail pane motivational phrases memoized \u2014 no longer flicker every render tick (fixes [#13](https://github.com/cesarandreslopez/sidekick-agent-hub/issues/13))\n\n### Changed\n\n- **Simplified Logo**: Replaced 6-line ASCII robot art with compact text header in splash, help, and changelog overlays\n- **Removed Dead Code**: Removed unused `getSplashContent()` and `HELP_HEADER` exports from branding module\n\n## [0.13.3] - 2026-03-04\n\n_No CLI-specific changes in this release._\n\n## [0.13.2] - 2026-03-04\n\n_No CLI-specific changes in this release._\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';
60758
60908
  }
60759
60909
  });
60760
60910
 
@@ -60879,6 +61029,7 @@ function Dashboard({ panels, metrics, staticData, isPinned, pendingSessionPath,
60879
61029
  const { columns, rows } = useTerminalSize();
60880
61030
  const toastIdRef = (0, import_react36.useRef)(0);
60881
61031
  const lastAlertCountRef = (0, import_react36.useRef)(0);
61032
+ const lastQuotaAlertKeyRef = (0, import_react36.useRef)(null);
60882
61033
  const alertsInitRef = (0, import_react36.useRef)(false);
60883
61034
  const prevDetailLineCountRef = (0, import_react36.useRef)(0);
60884
61035
  (0, import_react36.useEffect)(() => {
@@ -60917,6 +61068,20 @@ function Dashboard({ panels, metrics, staticData, isPinned, pendingSessionPath,
60917
61068
  dispatch({ type: "REMOVE_TOAST", id });
60918
61069
  }, durations[severity]);
60919
61070
  }, []);
61071
+ (0, import_react36.useEffect)(() => {
61072
+ if (metrics.providerId !== "claude-code") {
61073
+ lastQuotaAlertKeyRef.current = null;
61074
+ return;
61075
+ }
61076
+ const descriptor = (0, import_sidekick_shared12.describeQuotaFailure)(metrics.quota);
61077
+ if (!descriptor) {
61078
+ lastQuotaAlertKeyRef.current = null;
61079
+ return;
61080
+ }
61081
+ if (lastQuotaAlertKeyRef.current === descriptor.alertKey) return;
61082
+ lastQuotaAlertKeyRef.current = descriptor.alertKey;
61083
+ addToast(`${descriptor.title}: ${descriptor.message}`, descriptor.severity);
61084
+ }, [addToast, metrics.providerId, metrics.quota]);
60920
61085
  const panel = panels[state.activePanelIndex];
60921
61086
  const tooSmall = columns < MIN_SCREEN_WIDTH || rows < MIN_SCREEN_HEIGHT;
60922
61087
  const getSideWidth = () => {
@@ -62837,21 +63002,28 @@ async function quotaAction(_opts, cmd) {
62837
63002
  process.stdout.write(JSON.stringify(quota, null, 2) + "\n");
62838
63003
  return;
62839
63004
  }
63005
+ const descriptor = (0, import_sidekick_shared23.describeQuotaFailure)(quota);
62840
63006
  let msg;
62841
- switch (quota.error) {
62842
- case "no-credentials":
62843
- msg = "No Claude Code credentials found. Sign in with `claude` first.";
62844
- break;
62845
- case "auth-failed":
62846
- msg = "Authentication failed. Try signing in to Claude Code again.";
62847
- break;
62848
- case "network-error":
62849
- msg = "Could not reach the Anthropic API. Check your connection.";
62850
- break;
62851
- default:
62852
- msg = quota.error ?? "Unknown error fetching quota.";
63007
+ let color = source_default.red;
63008
+ if (descriptor) {
63009
+ msg = [descriptor.title, descriptor.message, descriptor.detail].filter(Boolean).join(" ");
63010
+ color = descriptor.severity === "warning" ? source_default.yellow : descriptor.severity === "info" ? source_default.cyan : source_default.red;
63011
+ } else {
63012
+ switch (quota.error) {
63013
+ case "no-credentials":
63014
+ msg = "No Claude Code credentials found. Sign in with `claude` first.";
63015
+ break;
63016
+ case "auth-failed":
63017
+ msg = "Authentication failed. Try signing in to Claude Code again.";
63018
+ break;
63019
+ case "network-error":
63020
+ msg = "Could not reach the Anthropic API. Check your connection.";
63021
+ break;
63022
+ default:
63023
+ msg = quota.error ?? "Unknown error fetching quota.";
63024
+ }
62853
63025
  }
62854
- process.stderr.write(source_default.red(msg) + "\n");
63026
+ process.stderr.write(color(msg) + "\n");
62855
63027
  process.exit(1);
62856
63028
  }
62857
63029
  if (jsonOutput) {
@@ -62872,10 +63044,12 @@ async function quotaAction(_opts, cmd) {
62872
63044
  process.stdout.write(` ${source_default.dim("7-Day")} ${makeChalkBar(sevenPct, barWidth)} ${String(sevenPct).padStart(3)}%${sevenProj} ${source_default.dim("resets " + sevenReset)}
62873
63045
  `);
62874
63046
  }
63047
+ var import_sidekick_shared23;
62875
63048
  var init_quota = __esm({
62876
63049
  "src/commands/quota.ts"() {
62877
63050
  "use strict";
62878
63051
  init_source();
63052
+ import_sidekick_shared23 = __toESM(require_dist(), 1);
62879
63053
  init_QuotaService();
62880
63054
  }
62881
63055
  });
@@ -62888,7 +63062,7 @@ __export(status_exports, {
62888
63062
  async function statusAction(_opts, cmd) {
62889
63063
  const globalOpts = cmd.parent.opts();
62890
63064
  const jsonOutput = !!globalOpts.json;
62891
- const status = await (0, import_sidekick_shared23.fetchProviderStatus)();
63065
+ const status = await (0, import_sidekick_shared24.fetchProviderStatus)();
62892
63066
  if (jsonOutput) {
62893
63067
  process.stdout.write(JSON.stringify(status, null, 2) + "\n");
62894
63068
  return;
@@ -62925,12 +63099,12 @@ async function statusAction(_opts, cmd) {
62925
63099
  }
62926
63100
  }
62927
63101
  }
62928
- var import_sidekick_shared23;
63102
+ var import_sidekick_shared24;
62929
63103
  var init_status = __esm({
62930
63104
  "src/commands/status.ts"() {
62931
63105
  "use strict";
62932
63106
  init_source();
62933
- import_sidekick_shared23 = __toESM(require_dist(), 1);
63107
+ import_sidekick_shared24 = __toESM(require_dist(), 1);
62934
63108
  }
62935
63109
  });
62936
63110
 
@@ -62944,12 +63118,12 @@ async function handoffAction(_opts, cmd) {
62944
63118
  const workspacePath = globalOpts.project || process.cwd();
62945
63119
  const jsonOutput = !!globalOpts.json;
62946
63120
  try {
62947
- const rawSlug = (0, import_sidekick_shared24.getProjectSlugRaw)(workspacePath);
62948
- const resolvedSlug = (0, import_sidekick_shared24.getProjectSlug)(workspacePath);
63121
+ const rawSlug = (0, import_sidekick_shared25.getProjectSlugRaw)(workspacePath);
63122
+ const resolvedSlug = (0, import_sidekick_shared25.getProjectSlug)(workspacePath);
62949
63123
  const slugs = rawSlug !== resolvedSlug ? [rawSlug, resolvedSlug] : [rawSlug];
62950
63124
  let content = null;
62951
63125
  for (const slug of slugs) {
62952
- content = await (0, import_sidekick_shared24.readLatestHandoff)(slug);
63126
+ content = await (0, import_sidekick_shared25.readLatestHandoff)(slug);
62953
63127
  if (content) break;
62954
63128
  }
62955
63129
  if (!content) {
@@ -62974,37 +63148,37 @@ async function handoffAction(_opts, cmd) {
62974
63148
  process.exit(1);
62975
63149
  }
62976
63150
  }
62977
- var import_sidekick_shared24;
63151
+ var import_sidekick_shared25;
62978
63152
  var init_handoff = __esm({
62979
63153
  "src/commands/handoff.ts"() {
62980
63154
  "use strict";
62981
63155
  init_source();
62982
- import_sidekick_shared24 = __toESM(require_dist(), 1);
63156
+ import_sidekick_shared25 = __toESM(require_dist(), 1);
62983
63157
  }
62984
63158
  });
62985
63159
 
62986
63160
  // src/cli.ts
62987
63161
  function resolveProvider(opts) {
62988
63162
  const override = opts.provider && opts.provider !== "auto" ? opts.provider : void 0;
62989
- const id = override || (0, import_sidekick_shared25.detectProvider)(override);
63163
+ const id = override || (0, import_sidekick_shared26.detectProvider)(override);
62990
63164
  switch (id) {
62991
63165
  case "opencode":
62992
- return new import_sidekick_shared26.OpenCodeProvider();
63166
+ return new import_sidekick_shared27.OpenCodeProvider();
62993
63167
  case "codex":
62994
- return new import_sidekick_shared26.CodexProvider();
63168
+ return new import_sidekick_shared27.CodexProvider();
62995
63169
  case "claude-code":
62996
63170
  default:
62997
- return new import_sidekick_shared26.ClaudeCodeProvider();
63171
+ return new import_sidekick_shared27.ClaudeCodeProvider();
62998
63172
  }
62999
63173
  }
63000
- var import_sidekick_shared25, import_sidekick_shared26, program2, dashCmd, dumpCmd, ctxCmd, reportCmd, searchCmd, tasksCmd, decisionsCmd, notesCmd, statsCmd, quotaCmd, statusCmd, handoffCmd;
63174
+ var import_sidekick_shared26, import_sidekick_shared27, program2, dashCmd, dumpCmd, ctxCmd, reportCmd, searchCmd, tasksCmd, decisionsCmd, notesCmd, statsCmd, quotaCmd, statusCmd, handoffCmd;
63001
63175
  var init_cli = __esm({
63002
63176
  "src/cli.ts"() {
63003
63177
  init_esm();
63004
- import_sidekick_shared25 = __toESM(require_dist(), 1);
63005
63178
  import_sidekick_shared26 = __toESM(require_dist(), 1);
63179
+ import_sidekick_shared27 = __toESM(require_dist(), 1);
63006
63180
  program2 = new Command();
63007
- program2.name("sidekick").description("Query Sidekick project intelligence from the command line").version("0.13.7").option("--json", "Output as JSON").option("--project <path>", "Override project path (default: cwd)").option("--provider <id>", "Provider: claude-code, opencode, codex, auto (default: auto)");
63181
+ program2.name("sidekick").description("Query Sidekick project intelligence from the command line").version("0.13.8").option("--json", "Output as JSON").option("--project <path>", "Override project path (default: cwd)").option("--provider <id>", "Provider: claude-code, opencode, codex, auto (default: auto)");
63008
63182
  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) => {
63009
63183
  const { dashboardAction: dashboardAction2 } = await init_dashboard().then(() => dashboard_exports);
63010
63184
  return dashboardAction2(_opts, cmd);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sidekick-agent-hub",
3
- "version": "0.13.7",
3
+ "version": "0.13.8",
4
4
  "description": "Terminal dashboard for monitoring AI coding agent sessions",
5
5
  "type": "module",
6
6
  "bin": {