sidekick-agent-hub 0.14.2 → 0.15.2
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 +9 -5
- package/dist/sidekick-cli.mjs +228 -57
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -93,15 +93,19 @@ You can also press `r` in the TUI dashboard to generate a report for the current
|
|
|
93
93
|
sidekick status
|
|
94
94
|
```
|
|
95
95
|
|
|
96
|
-
Check
|
|
96
|
+
Check API health for both Claude (status.claude.com) and OpenAI (status.openai.com). Shows indicators with color coding (green/yellow/red), affected components, and active incident details. Use `--json` for machine-readable output. The dashboard also shows a status indicator in the status bar and Sessions Summary tab when the API is degraded.
|
|
97
97
|
|
|
98
|
-
##
|
|
98
|
+
## Quota & Rate Limits
|
|
99
99
|
|
|
100
100
|
```bash
|
|
101
101
|
sidekick quota
|
|
102
102
|
```
|
|
103
103
|
|
|
104
|
-
|
|
104
|
+
Provider-aware quota and rate-limit display. The command auto-detects the active provider:
|
|
105
|
+
|
|
106
|
+
- **Claude Code**: Shows Claude Max subscription quota — 5-hour and 7-day windows with color-coded progress bars, projections, and reset countdowns.
|
|
107
|
+
- **Codex**: Shows rate limits from the latest session's event stream — primary and secondary windows with progress bars and reset countdowns.
|
|
108
|
+
- **OpenCode**: Prints an informational message (no rate-limit data available).
|
|
105
109
|
|
|
106
110
|
```
|
|
107
111
|
Subscription Quota
|
|
@@ -110,9 +114,9 @@ Subscription Quota
|
|
|
110
114
|
7-Day ██████████████████████░░░░░░░░ 72% resets in 4d 6h
|
|
111
115
|
```
|
|
112
116
|
|
|
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
|
|
117
|
+
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/rate-limit state visible instead of hiding the section entirely.
|
|
114
118
|
|
|
115
|
-
Use `--json` for machine-readable output.
|
|
119
|
+
Use `--json` for machine-readable output. Use `--provider codex` to explicitly check Codex rate limits. Claude Code requires active credentials (read from the system Keychain on macOS, or `~/.claude/.credentials.json` on Linux/Windows). JSON output includes `failureKind`, `httpStatus`, and `retryAfterMs` on unavailable responses.
|
|
116
120
|
|
|
117
121
|
When multi-account is enabled, `sidekick quota` shows the active account email above the quota bars.
|
|
118
122
|
|
package/dist/sidekick-cli.mjs
CHANGED
|
@@ -8899,7 +8899,7 @@ var require_codex = __commonJS({
|
|
|
8899
8899
|
return this._wasTruncated;
|
|
8900
8900
|
}
|
|
8901
8901
|
};
|
|
8902
|
-
var
|
|
8902
|
+
var CodexProvider4 = class {
|
|
8903
8903
|
id = "codex";
|
|
8904
8904
|
displayName = "Codex CLI";
|
|
8905
8905
|
db = null;
|
|
@@ -9328,7 +9328,7 @@ var require_codex = __commonJS({
|
|
|
9328
9328
|
this.lastTokenUsageData = null;
|
|
9329
9329
|
}
|
|
9330
9330
|
};
|
|
9331
|
-
exports.CodexProvider =
|
|
9331
|
+
exports.CodexProvider = CodexProvider4;
|
|
9332
9332
|
}
|
|
9333
9333
|
});
|
|
9334
9334
|
|
|
@@ -11496,7 +11496,7 @@ var require_factory = __commonJS({
|
|
|
11496
11496
|
};
|
|
11497
11497
|
}();
|
|
11498
11498
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11499
|
-
exports.createWatcher =
|
|
11499
|
+
exports.createWatcher = createWatcher5;
|
|
11500
11500
|
var os5 = __importStar(__require("os"));
|
|
11501
11501
|
var path7 = __importStar(__require("path"));
|
|
11502
11502
|
var jsonlWatcher_1 = require_jsonlWatcher();
|
|
@@ -11507,7 +11507,7 @@ var require_factory = __commonJS({
|
|
|
11507
11507
|
return path7.join(xdg, "opencode");
|
|
11508
11508
|
return path7.join(os5.homedir(), ".local", "share", "opencode");
|
|
11509
11509
|
}
|
|
11510
|
-
function
|
|
11510
|
+
function createWatcher5(options) {
|
|
11511
11511
|
const { provider, workspacePath, sessionId, callbacks } = options;
|
|
11512
11512
|
const sessions = provider.findAllSessions(workspacePath);
|
|
11513
11513
|
if (sessions.length === 0) {
|
|
@@ -17362,8 +17362,9 @@ var require_providerStatus = __commonJS({
|
|
|
17362
17362
|
"use strict";
|
|
17363
17363
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17364
17364
|
exports.fetchProviderStatus = fetchProviderStatus3;
|
|
17365
|
-
|
|
17366
|
-
var
|
|
17365
|
+
exports.fetchOpenAIStatus = fetchOpenAIStatus3;
|
|
17366
|
+
var CLAUDE_BASE = "https://status.claude.com";
|
|
17367
|
+
var OPENAI_BASE = "https://status.openai.com";
|
|
17367
17368
|
function fallbackState() {
|
|
17368
17369
|
return {
|
|
17369
17370
|
indicator: "none",
|
|
@@ -17373,9 +17374,9 @@ var require_providerStatus = __commonJS({
|
|
|
17373
17374
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
17374
17375
|
};
|
|
17375
17376
|
}
|
|
17376
|
-
async function
|
|
17377
|
+
async function fetchStatusPage(baseUrl) {
|
|
17377
17378
|
try {
|
|
17378
|
-
const statusRes = await fetch(
|
|
17379
|
+
const statusRes = await fetch(`${baseUrl}/api/v2/status.json`);
|
|
17379
17380
|
if (!statusRes.ok)
|
|
17380
17381
|
return fallbackState();
|
|
17381
17382
|
const statusData = await statusRes.json();
|
|
@@ -17385,7 +17386,7 @@ var require_providerStatus = __commonJS({
|
|
|
17385
17386
|
if (indicator === "none") {
|
|
17386
17387
|
return { indicator, description, affectedComponents: [], activeIncident: null, updatedAt };
|
|
17387
17388
|
}
|
|
17388
|
-
const summaryRes = await fetch(
|
|
17389
|
+
const summaryRes = await fetch(`${baseUrl}/api/v2/summary.json`);
|
|
17389
17390
|
if (!summaryRes.ok) {
|
|
17390
17391
|
return { indicator, description, affectedComponents: [], activeIncident: null, updatedAt };
|
|
17391
17392
|
}
|
|
@@ -17403,6 +17404,12 @@ var require_providerStatus = __commonJS({
|
|
|
17403
17404
|
return fallbackState();
|
|
17404
17405
|
}
|
|
17405
17406
|
}
|
|
17407
|
+
async function fetchProviderStatus3() {
|
|
17408
|
+
return fetchStatusPage(CLAUDE_BASE);
|
|
17409
|
+
}
|
|
17410
|
+
async function fetchOpenAIStatus3() {
|
|
17411
|
+
return fetchStatusPage(OPENAI_BASE);
|
|
17412
|
+
}
|
|
17406
17413
|
}
|
|
17407
17414
|
});
|
|
17408
17415
|
|
|
@@ -17413,7 +17420,7 @@ var require_dist = __commonJS({
|
|
|
17413
17420
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17414
17421
|
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;
|
|
17415
17422
|
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;
|
|
17416
|
-
exports.fetchProviderStatus = exports.DEFAULT_CONTEXT_WINDOW = exports.getModelContextWindowSize = exports.describeQuotaFailure = exports.fetchQuota = exports.isMultiAccountEnabled = exports.getActiveAccount = exports.listAccounts = exports.removeAccount = exports.switchToAccount = exports.addCurrentAccount = exports.readActiveClaudeAccount = exports.writeAccountRegistry = exports.readAccountRegistry = exports.getAccountsDir = exports.readClaudeMaxAccessTokenSync = exports.readClaudeMaxCredentials = exports.writeActiveCredentials = exports.readActiveCredentials = exports.openInBrowser = exports.parseTranscript = exports.generateHtmlReport = exports.PatternExtractor = void 0;
|
|
17423
|
+
exports.fetchOpenAIStatus = exports.fetchProviderStatus = exports.DEFAULT_CONTEXT_WINDOW = exports.getModelContextWindowSize = exports.describeQuotaFailure = exports.fetchQuota = exports.isMultiAccountEnabled = exports.getActiveAccount = exports.listAccounts = exports.removeAccount = exports.switchToAccount = exports.addCurrentAccount = exports.readActiveClaudeAccount = exports.writeAccountRegistry = exports.readAccountRegistry = exports.getAccountsDir = exports.readClaudeMaxAccessTokenSync = exports.readClaudeMaxCredentials = exports.writeActiveCredentials = exports.readActiveCredentials = exports.openInBrowser = exports.parseTranscript = exports.generateHtmlReport = exports.PatternExtractor = void 0;
|
|
17417
17424
|
var taskPersistence_1 = require_taskPersistence();
|
|
17418
17425
|
Object.defineProperty(exports, "TASK_PERSISTENCE_SCHEMA_VERSION", { enumerable: true, get: function() {
|
|
17419
17426
|
return taskPersistence_1.TASK_PERSISTENCE_SCHEMA_VERSION;
|
|
@@ -17834,6 +17841,9 @@ var require_dist = __commonJS({
|
|
|
17834
17841
|
Object.defineProperty(exports, "fetchProviderStatus", { enumerable: true, get: function() {
|
|
17835
17842
|
return providerStatus_1.fetchProviderStatus;
|
|
17836
17843
|
} });
|
|
17844
|
+
Object.defineProperty(exports, "fetchOpenAIStatus", { enumerable: true, get: function() {
|
|
17845
|
+
return providerStatus_1.fetchOpenAIStatus;
|
|
17846
|
+
} });
|
|
17837
17847
|
}
|
|
17838
17848
|
});
|
|
17839
17849
|
|
|
@@ -19320,8 +19330,9 @@ var init_DashboardState = __esm({
|
|
|
19320
19330
|
_providerName;
|
|
19321
19331
|
// Quota (external state from OAuth API or Codex rate limits)
|
|
19322
19332
|
_quota = null;
|
|
19323
|
-
// Provider status (external state from status.claude.com)
|
|
19333
|
+
// Provider status (external state from status.claude.com / status.openai.com)
|
|
19324
19334
|
_providerStatus = null;
|
|
19335
|
+
_openaiStatus = null;
|
|
19325
19336
|
// Update availability (external state)
|
|
19326
19337
|
_updateInfo = null;
|
|
19327
19338
|
// Session ID (for plan persistence)
|
|
@@ -19345,6 +19356,7 @@ var init_DashboardState = __esm({
|
|
|
19345
19356
|
this._providerName = void 0;
|
|
19346
19357
|
this._quota = null;
|
|
19347
19358
|
this._providerStatus = null;
|
|
19359
|
+
this._openaiStatus = null;
|
|
19348
19360
|
this._updateInfo = null;
|
|
19349
19361
|
this._sessionId = void 0;
|
|
19350
19362
|
this._lastKnownCompactionCount = 0;
|
|
@@ -19505,10 +19517,14 @@ var init_DashboardState = __esm({
|
|
|
19505
19517
|
setQuota(quota) {
|
|
19506
19518
|
this._quota = quota;
|
|
19507
19519
|
}
|
|
19508
|
-
/** Update provider status from status.claude.com polling. */
|
|
19520
|
+
/** Update Claude provider status from status.claude.com polling. */
|
|
19509
19521
|
setProviderStatus(status) {
|
|
19510
19522
|
this._providerStatus = status;
|
|
19511
19523
|
}
|
|
19524
|
+
/** Update OpenAI provider status from status.openai.com polling. */
|
|
19525
|
+
setOpenAIStatus(status) {
|
|
19526
|
+
this._openaiStatus = status;
|
|
19527
|
+
}
|
|
19512
19528
|
/** Set update availability info from UpdateCheckService. */
|
|
19513
19529
|
setUpdateInfo(info) {
|
|
19514
19530
|
this._updateInfo = info;
|
|
@@ -19614,6 +19630,7 @@ var init_DashboardState = __esm({
|
|
|
19614
19630
|
compactionEvents,
|
|
19615
19631
|
quota: this._quota,
|
|
19616
19632
|
providerStatus: this._providerStatus,
|
|
19633
|
+
openaiStatus: this._openaiStatus,
|
|
19617
19634
|
eventCount: m.eventCount,
|
|
19618
19635
|
sessionStartTime: m.sessionStartTime ?? void 0,
|
|
19619
19636
|
currentModel: m.currentModel ?? void 0,
|
|
@@ -19946,16 +19963,22 @@ var init_ProviderStatusService = __esm({
|
|
|
19946
19963
|
ProviderStatusService = class {
|
|
19947
19964
|
_interval = null;
|
|
19948
19965
|
_cached = null;
|
|
19966
|
+
_cachedOpenAI = null;
|
|
19949
19967
|
_callback = null;
|
|
19950
|
-
|
|
19968
|
+
_openAICallback = null;
|
|
19969
|
+
/** Register a callback for Claude status updates. */
|
|
19951
19970
|
onUpdate(cb) {
|
|
19952
19971
|
this._callback = cb;
|
|
19953
19972
|
}
|
|
19973
|
+
/** Register a callback for OpenAI status updates. */
|
|
19974
|
+
onOpenAIUpdate(cb) {
|
|
19975
|
+
this._openAICallback = cb;
|
|
19976
|
+
}
|
|
19954
19977
|
/** Start polling. Fetches immediately, then every 60s. */
|
|
19955
19978
|
start() {
|
|
19956
19979
|
if (this._interval) return;
|
|
19957
|
-
this.
|
|
19958
|
-
this._interval = setInterval(() => this.
|
|
19980
|
+
this._fetchAll();
|
|
19981
|
+
this._interval = setInterval(() => this._fetchAll(), REFRESH_MS2);
|
|
19959
19982
|
}
|
|
19960
19983
|
/** Stop polling. */
|
|
19961
19984
|
stop() {
|
|
@@ -19964,18 +19987,27 @@ var init_ProviderStatusService = __esm({
|
|
|
19964
19987
|
this._interval = null;
|
|
19965
19988
|
}
|
|
19966
19989
|
}
|
|
19967
|
-
/** Get the last fetched status state. */
|
|
19990
|
+
/** Get the last fetched Claude status state. */
|
|
19968
19991
|
getCached() {
|
|
19969
19992
|
return this._cached;
|
|
19970
19993
|
}
|
|
19994
|
+
/** Get the last fetched OpenAI status state. */
|
|
19995
|
+
getCachedOpenAI() {
|
|
19996
|
+
return this._cachedOpenAI;
|
|
19997
|
+
}
|
|
19971
19998
|
/** Single fetch — no polling. */
|
|
19972
19999
|
async fetchOnce() {
|
|
19973
20000
|
return (0, import_sidekick_shared6.fetchProviderStatus)();
|
|
19974
20001
|
}
|
|
19975
|
-
async
|
|
19976
|
-
const
|
|
19977
|
-
|
|
19978
|
-
|
|
20002
|
+
async _fetchAll() {
|
|
20003
|
+
const [claude, openai] = await Promise.all([
|
|
20004
|
+
(0, import_sidekick_shared6.fetchProviderStatus)(),
|
|
20005
|
+
(0, import_sidekick_shared6.fetchOpenAIStatus)()
|
|
20006
|
+
]);
|
|
20007
|
+
this._cached = claude;
|
|
20008
|
+
this._callback?.(claude);
|
|
20009
|
+
this._cachedOpenAI = openai;
|
|
20010
|
+
this._openAICallback?.(openai);
|
|
19979
20011
|
}
|
|
19980
20012
|
};
|
|
19981
20013
|
}
|
|
@@ -20012,7 +20044,7 @@ var init_UpdateCheckService = __esm({
|
|
|
20012
20044
|
/** Run the update check (one-shot). */
|
|
20013
20045
|
async check() {
|
|
20014
20046
|
try {
|
|
20015
|
-
const current = "0.
|
|
20047
|
+
const current = "0.15.2";
|
|
20016
20048
|
const cached = this.readCache();
|
|
20017
20049
|
let latest;
|
|
20018
20050
|
if (cached && Date.now() - cached.checkedAt < CACHE_TTL_MS) {
|
|
@@ -21578,9 +21610,10 @@ ${hint}{/grey-fg}`;
|
|
|
21578
21610
|
lines.push(` ${modelName.padEnd(20)} {bold}${String(ms.calls).padStart(4)}{/bold}{grey-fg} calls{/grey-fg} {green-fg}$${ms.cost.toFixed(4)}{/green-fg}`);
|
|
21579
21611
|
}
|
|
21580
21612
|
}
|
|
21613
|
+
const quotaLabel = m.providerId === "codex" ? "Rate Limits" : "Quota";
|
|
21581
21614
|
if (m.quota?.available) {
|
|
21582
21615
|
const q = m.quota;
|
|
21583
|
-
lines.push("", sectionHeader(
|
|
21616
|
+
lines.push("", sectionHeader(quotaLabel, w2));
|
|
21584
21617
|
const fiveColor = getUtilizationColor(q.fiveHour.utilization);
|
|
21585
21618
|
const fiveBar = makeColorBar(q.fiveHour.utilization, 18, fiveColor);
|
|
21586
21619
|
const fiveProj = q.projectedFiveHour != null ? (() => {
|
|
@@ -21595,11 +21628,11 @@ ${hint}{/grey-fg}`;
|
|
|
21595
21628
|
return ` {grey-fg}\u2192{/grey-fg} {${pc}-fg}${q.projectedSevenDay.toFixed(0)}%{/${pc}-fg}`;
|
|
21596
21629
|
})() : "";
|
|
21597
21630
|
lines.push(` {grey-fg}7d{/grey-fg} ${sevenBar} {bold}${q.sevenDay.utilization.toFixed(0)}%{/bold}${sevenProj}`);
|
|
21598
|
-
} else if (m.providerId === "claude-code" && m.quota) {
|
|
21631
|
+
} else if ((m.providerId === "claude-code" || m.providerId === "codex") && m.quota) {
|
|
21599
21632
|
const descriptor = (0, import_sidekick_shared8.describeQuotaFailure)(m.quota);
|
|
21600
21633
|
if (descriptor) {
|
|
21601
21634
|
const severityColor = descriptor.severity === "warning" ? "yellow" : descriptor.severity === "info" ? "cyan" : "red";
|
|
21602
|
-
lines.push("", sectionHeader(
|
|
21635
|
+
lines.push("", sectionHeader(quotaLabel, w2));
|
|
21603
21636
|
lines.push(` {${severityColor}-fg}${descriptor.title}{/${severityColor}-fg}`);
|
|
21604
21637
|
const failureText = [descriptor.message, descriptor.detail].filter(Boolean).join(" ");
|
|
21605
21638
|
const quotaTextWidth = Math.max(20, detailWidth() - 4);
|
|
@@ -21608,19 +21641,24 @@ ${hint}{/grey-fg}`;
|
|
|
21608
21641
|
}
|
|
21609
21642
|
}
|
|
21610
21643
|
}
|
|
21611
|
-
|
|
21612
|
-
|
|
21613
|
-
|
|
21614
|
-
|
|
21615
|
-
|
|
21616
|
-
|
|
21617
|
-
const
|
|
21618
|
-
lines.push(
|
|
21619
|
-
|
|
21620
|
-
|
|
21621
|
-
|
|
21622
|
-
|
|
21623
|
-
|
|
21644
|
+
const statusEntries = [
|
|
21645
|
+
{ label: "Claude API Status", status: m.providerStatus },
|
|
21646
|
+
{ label: "OpenAI API Status", status: m.openaiStatus }
|
|
21647
|
+
];
|
|
21648
|
+
for (const { label, status: ps } of statusEntries) {
|
|
21649
|
+
if (ps && ps.indicator !== "none") {
|
|
21650
|
+
const statusColor = ps.indicator === "minor" ? "yellow" : "red";
|
|
21651
|
+
lines.push("", sectionHeader(label, w2));
|
|
21652
|
+
lines.push(` {${statusColor}-fg}\u25CF ${ps.description}{/${statusColor}-fg}`);
|
|
21653
|
+
for (const c2 of ps.affectedComponents) {
|
|
21654
|
+
const cColor = c2.status.includes("major") ? "red" : "yellow";
|
|
21655
|
+
lines.push(` {${cColor}-fg}\u2022{/${cColor}-fg} ${c2.name} {grey-fg}\u2014 ${c2.status.replace(/_/g, " ")}{/grey-fg}`);
|
|
21656
|
+
}
|
|
21657
|
+
if (ps.activeIncident) {
|
|
21658
|
+
lines.push(` {${statusColor}-fg}${ps.activeIncident.name}{/${statusColor}-fg}`);
|
|
21659
|
+
if (ps.activeIncident.shortlink) {
|
|
21660
|
+
lines.push(` {grey-fg}${ps.activeIncident.shortlink}{/grey-fg}`);
|
|
21661
|
+
}
|
|
21624
21662
|
}
|
|
21625
21663
|
}
|
|
21626
21664
|
}
|
|
@@ -60601,19 +60639,22 @@ function StatusBar({
|
|
|
60601
60639
|
matchCount,
|
|
60602
60640
|
totalCount,
|
|
60603
60641
|
updateInfo,
|
|
60604
|
-
providerStatus
|
|
60642
|
+
providerStatus,
|
|
60643
|
+
openaiStatus
|
|
60605
60644
|
}) {
|
|
60606
60645
|
const evtLabel = eventCount > 0 ? `${eventCount} events` : "waiting...";
|
|
60607
60646
|
const permissionColor = permissionMode === "bypassPermissions" ? "red" : permissionMode === "acceptEdits" ? "magenta" : permissionMode === "plan" ? "green" : void 0;
|
|
60608
60647
|
const permissionLabel = permissionMode === "bypassPermissions" ? "BYPASS" : permissionMode === "acceptEdits" ? "EDITS" : permissionMode === "plan" ? "PLAN" : void 0;
|
|
60609
60648
|
const statusIndicator = providerStatus && providerStatus.indicator !== "none";
|
|
60610
60649
|
const statusColor = providerStatus?.indicator === "minor" ? "yellow" : "red";
|
|
60650
|
+
const openaiIndicator = openaiStatus && openaiStatus.indicator !== "none";
|
|
60651
|
+
const openaiColor = openaiStatus?.indicator === "minor" ? "yellow" : "red";
|
|
60611
60652
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Box_default, { height: 1, width: "100%", children: [
|
|
60612
60653
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Box_default, { children: [
|
|
60613
60654
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: parseBlessedTags(BRAND_INLINE) }),
|
|
60614
60655
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { dimColor: true, children: [
|
|
60615
60656
|
" v",
|
|
60616
|
-
"0.
|
|
60657
|
+
"0.15.2"
|
|
60617
60658
|
] }),
|
|
60618
60659
|
updateInfo && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { color: "yellow", children: [
|
|
60619
60660
|
" (v",
|
|
@@ -60652,10 +60693,22 @@ function StatusBar({
|
|
|
60652
60693
|
] }),
|
|
60653
60694
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { color: statusColor, children: [
|
|
60654
60695
|
"\u25CF",
|
|
60655
|
-
"
|
|
60696
|
+
" Claude ",
|
|
60656
60697
|
providerStatus.indicator
|
|
60657
60698
|
] })
|
|
60658
60699
|
] }),
|
|
60700
|
+
openaiIndicator && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
60701
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { dimColor: true, children: [
|
|
60702
|
+
" ",
|
|
60703
|
+
"\u2502",
|
|
60704
|
+
" "
|
|
60705
|
+
] }),
|
|
60706
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { color: openaiColor, children: [
|
|
60707
|
+
"\u25CF",
|
|
60708
|
+
" OpenAI ",
|
|
60709
|
+
openaiStatus.indicator
|
|
60710
|
+
] })
|
|
60711
|
+
] }),
|
|
60659
60712
|
filterString && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { color: "yellow", children: [
|
|
60660
60713
|
' filter: "',
|
|
60661
60714
|
filterString,
|
|
@@ -60991,7 +61044,7 @@ function ChangelogOverlay({ entries, scrollOffset }) {
|
|
|
60991
61044
|
" ",
|
|
60992
61045
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Text, { bold: true, color: "cyan", children: [
|
|
60993
61046
|
"Terminal Dashboard v",
|
|
60994
|
-
"0.
|
|
61047
|
+
"0.15.2"
|
|
60995
61048
|
] }),
|
|
60996
61049
|
latestDate ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Text, { color: "gray", children: [
|
|
60997
61050
|
" \u2014 ",
|
|
@@ -61313,7 +61366,7 @@ var init_mouse = __esm({
|
|
|
61313
61366
|
var CHANGELOG_default;
|
|
61314
61367
|
var init_CHANGELOG = __esm({
|
|
61315
61368
|
"CHANGELOG.md"() {
|
|
61316
|
-
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.14.2] - 2026-03-16\n\n### Fixed\n\n- **Quota polling interval**: Reduced quota refresh from every 30 seconds to every 5 minutes to avoid unnecessary API calls\n- **SessionsPanel `detailWidth()` call**: Removed unused parameter from `detailWidth()` in the Sessions panel quota rendering\n\n## [0.14.1] - 2026-03-14\n\n### Fixed\n\n- **Per-model context window sizes**: Dashboard context gauge now shows correct utilization for Claude Opus 4.6 (1M context) and other models with non-200K windows\n\n### Changed\n\n- **Shared model context lookup**: CLI dashboard now uses the centralized `getModelContextWindowSize()` from `sidekick-shared` instead of a local duplicate map\n\n## [0.14.0] - 2026-03-12\n\n### Added\n\n- **`sidekick account` Command**: Manage Claude Code accounts from the terminal \u2014 list saved accounts, add the current account with an optional label, switch to the next or a specific account, and remove accounts. Supports `--json` output for scripting\n- **Quota Account Label**: `sidekick quota` now shows the active account email and label above the quota bars when multi-account is enabled\n- **macOS Keychain Support**: `sidekick account` and `sidekick quota` now read and write credentials via the system Keychain on macOS, fixing account switching and quota checks on Mac\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';
|
|
61369
|
+
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.15.2] - 2026-03-18\n\n### Fixed\n\n- **CLI help descriptions**: Updated `quota` and `status` command descriptions to reflect provider-aware behavior\n- **`sidekick quota --provider`**: Added local `--provider` option so `sidekick quota --provider codex` works naturally\n\n## [0.15.0] - 2026-03-18\n\n### Added\n\n- **OpenAI status page monitoring**: CLI dashboard now shows OpenAI API status alongside Claude API status\n- **Codex rate limits in dashboard**: Sessions panel displays Codex rate-limit data with "Rate Limits" header instead of "Quota"\n- **Provider-aware `sidekick quota` command**: Detects active provider and shows Codex rate limits, Claude subscription quota, or an informational message for OpenCode\n\n### Fixed\n\n- **QuotaService polling for Codex**: Dashboard no longer starts Claude OAuth quota polling when the active provider is Codex\n\n## [0.14.2] - 2026-03-16\n\n### Fixed\n\n- **Quota polling interval**: Reduced quota refresh from every 30 seconds to every 5 minutes to avoid unnecessary API calls\n- **SessionsPanel `detailWidth()` call**: Removed unused parameter from `detailWidth()` in the Sessions panel quota rendering\n\n## [0.14.1] - 2026-03-14\n\n### Fixed\n\n- **Per-model context window sizes**: Dashboard context gauge now shows correct utilization for Claude Opus 4.6 (1M context) and other models with non-200K windows\n\n### Changed\n\n- **Shared model context lookup**: CLI dashboard now uses the centralized `getModelContextWindowSize()` from `sidekick-shared` instead of a local duplicate map\n\n## [0.14.0] - 2026-03-12\n\n### Added\n\n- **`sidekick account` Command**: Manage Claude Code accounts from the terminal \u2014 list saved accounts, add the current account with an optional label, switch to the next or a specific account, and remove accounts. Supports `--json` output for scripting\n- **Quota Account Label**: `sidekick quota` now shows the active account email and label above the quota bars when multi-account is enabled\n- **macOS Keychain Support**: `sidekick account` and `sidekick quota` now read and write credentials via the system Keychain on macOS, fixing account switching and quota checks on Mac\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';
|
|
61317
61370
|
}
|
|
61318
61371
|
});
|
|
61319
61372
|
|
|
@@ -61996,7 +62049,8 @@ function Dashboard({ panels, metrics, staticData, isPinned, pendingSessionPath,
|
|
|
61996
62049
|
matchCount: currentItems.length,
|
|
61997
62050
|
totalCount: panel.getItems(metrics, staticData).length,
|
|
61998
62051
|
updateInfo: metrics.updateInfo,
|
|
61999
|
-
providerStatus: metrics.providerStatus
|
|
62052
|
+
providerStatus: metrics.providerStatus,
|
|
62053
|
+
openaiStatus: metrics.openaiStatus
|
|
62000
62054
|
}
|
|
62001
62055
|
),
|
|
62002
62056
|
state.overlay === "context-menu" && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
@@ -62391,6 +62445,10 @@ async function dashboardAction(_opts, cmd) {
|
|
|
62391
62445
|
state.setProviderStatus(status);
|
|
62392
62446
|
scheduleRender();
|
|
62393
62447
|
});
|
|
62448
|
+
providerStatusService.onOpenAIUpdate((status) => {
|
|
62449
|
+
state.setOpenAIStatus(status);
|
|
62450
|
+
scheduleRender();
|
|
62451
|
+
});
|
|
62394
62452
|
let stopped = false;
|
|
62395
62453
|
function cleanup() {
|
|
62396
62454
|
if (stopped) return;
|
|
@@ -62471,7 +62529,9 @@ async function dashboardAction(_opts, cmd) {
|
|
|
62471
62529
|
}
|
|
62472
62530
|
} catch {
|
|
62473
62531
|
}
|
|
62474
|
-
|
|
62532
|
+
if (activeProvider.id === "claude-code") {
|
|
62533
|
+
quotaService.start();
|
|
62534
|
+
}
|
|
62475
62535
|
providerStatusService.start();
|
|
62476
62536
|
updateCheckService.check();
|
|
62477
62537
|
scheduleRender();
|
|
@@ -63403,7 +63463,28 @@ function formatTimeUntil(isoString) {
|
|
|
63403
63463
|
}
|
|
63404
63464
|
async function quotaAction(_opts, cmd) {
|
|
63405
63465
|
const globalOpts = cmd.parent.opts();
|
|
63466
|
+
const localOpts = cmd.opts();
|
|
63406
63467
|
const jsonOutput = !!globalOpts.json;
|
|
63468
|
+
const providerOpts = localOpts.provider ? { provider: localOpts.provider } : globalOpts;
|
|
63469
|
+
const provider = resolveProvider(providerOpts);
|
|
63470
|
+
if (provider.id === "opencode") {
|
|
63471
|
+
provider.dispose();
|
|
63472
|
+
const msg = "OpenCode does not provide rate-limit data.";
|
|
63473
|
+
if (jsonOutput) {
|
|
63474
|
+
process.stdout.write(JSON.stringify({ available: false, error: msg }, null, 2) + "\n");
|
|
63475
|
+
} else {
|
|
63476
|
+
process.stderr.write(source_default.yellow(msg) + "\n");
|
|
63477
|
+
}
|
|
63478
|
+
return;
|
|
63479
|
+
}
|
|
63480
|
+
if (provider.id === "codex") {
|
|
63481
|
+
await codexQuotaAction(provider, globalOpts, jsonOutput);
|
|
63482
|
+
return;
|
|
63483
|
+
}
|
|
63484
|
+
provider.dispose();
|
|
63485
|
+
await claudeQuotaAction(jsonOutput);
|
|
63486
|
+
}
|
|
63487
|
+
async function claudeQuotaAction(jsonOutput) {
|
|
63407
63488
|
const service = new QuotaService();
|
|
63408
63489
|
const quota = await service.fetchOnce();
|
|
63409
63490
|
if (!quota.available) {
|
|
@@ -63458,12 +63539,92 @@ async function quotaAction(_opts, cmd) {
|
|
|
63458
63539
|
process.stdout.write(` ${source_default.dim("7-Day")} ${makeChalkBar(sevenPct, barWidth)} ${String(sevenPct).padStart(3)}%${sevenProj} ${source_default.dim("resets " + sevenReset)}
|
|
63459
63540
|
`);
|
|
63460
63541
|
}
|
|
63542
|
+
async function codexQuotaAction(provider, globalOpts, jsonOutput) {
|
|
63543
|
+
const workspacePath = globalOpts.project || process.cwd();
|
|
63544
|
+
const sessions = provider.findAllSessions(workspacePath);
|
|
63545
|
+
if (sessions.length === 0) {
|
|
63546
|
+
provider.dispose();
|
|
63547
|
+
const msg = "No active Codex session. Rate limits are available only during active sessions.";
|
|
63548
|
+
if (jsonOutput) {
|
|
63549
|
+
process.stdout.write(JSON.stringify({ available: false, error: msg }, null, 2) + "\n");
|
|
63550
|
+
} else {
|
|
63551
|
+
process.stderr.write(source_default.yellow(msg) + "\n");
|
|
63552
|
+
}
|
|
63553
|
+
return;
|
|
63554
|
+
}
|
|
63555
|
+
const captured = { rl: void 0 };
|
|
63556
|
+
try {
|
|
63557
|
+
const result = (0, import_sidekick_shared24.createWatcher)({
|
|
63558
|
+
provider,
|
|
63559
|
+
workspacePath,
|
|
63560
|
+
callbacks: {
|
|
63561
|
+
onEvent: (event) => {
|
|
63562
|
+
if (event.rateLimits) {
|
|
63563
|
+
captured.rl = event.rateLimits;
|
|
63564
|
+
}
|
|
63565
|
+
},
|
|
63566
|
+
onError: () => {
|
|
63567
|
+
}
|
|
63568
|
+
}
|
|
63569
|
+
});
|
|
63570
|
+
result.watcher.start(true);
|
|
63571
|
+
result.watcher.stop();
|
|
63572
|
+
} catch {
|
|
63573
|
+
}
|
|
63574
|
+
provider.dispose();
|
|
63575
|
+
const rateLimits = captured.rl;
|
|
63576
|
+
if (!rateLimits) {
|
|
63577
|
+
const msg = "No rate-limit data found in latest Codex session.";
|
|
63578
|
+
if (jsonOutput) {
|
|
63579
|
+
process.stdout.write(JSON.stringify({ available: false, error: msg }, null, 2) + "\n");
|
|
63580
|
+
} else {
|
|
63581
|
+
process.stderr.write(source_default.yellow(msg) + "\n");
|
|
63582
|
+
}
|
|
63583
|
+
return;
|
|
63584
|
+
}
|
|
63585
|
+
const primary = rateLimits.primary;
|
|
63586
|
+
const secondary = rateLimits.secondary;
|
|
63587
|
+
if (!primary && !secondary) {
|
|
63588
|
+
const msg = "No rate-limit data found in latest Codex session.";
|
|
63589
|
+
if (jsonOutput) {
|
|
63590
|
+
process.stdout.write(JSON.stringify({ available: false, error: msg }, null, 2) + "\n");
|
|
63591
|
+
} else {
|
|
63592
|
+
process.stderr.write(source_default.yellow(msg) + "\n");
|
|
63593
|
+
}
|
|
63594
|
+
return;
|
|
63595
|
+
}
|
|
63596
|
+
const quota = {
|
|
63597
|
+
fiveHour: primary ? { utilization: primary.usedPercent, resetsAt: new Date(primary.resetsAt * 1e3).toISOString() } : { utilization: 0, resetsAt: "" },
|
|
63598
|
+
sevenDay: secondary ? { utilization: secondary.usedPercent, resetsAt: new Date(secondary.resetsAt * 1e3).toISOString() } : { utilization: 0, resetsAt: "" },
|
|
63599
|
+
available: true
|
|
63600
|
+
};
|
|
63601
|
+
if (jsonOutput) {
|
|
63602
|
+
process.stdout.write(JSON.stringify(quota, null, 2) + "\n");
|
|
63603
|
+
return;
|
|
63604
|
+
}
|
|
63605
|
+
const barWidth = 30;
|
|
63606
|
+
const fivePct = Math.round(quota.fiveHour.utilization);
|
|
63607
|
+
const sevenPct = Math.round(quota.sevenDay.utilization);
|
|
63608
|
+
const fiveReset = quota.fiveHour.resetsAt ? formatTimeUntil(quota.fiveHour.resetsAt) : "";
|
|
63609
|
+
const sevenReset = quota.sevenDay.resetsAt ? formatTimeUntil(quota.sevenDay.resetsAt) : "";
|
|
63610
|
+
process.stdout.write(source_default.bold("Rate Limits\n"));
|
|
63611
|
+
process.stdout.write(source_default.dim("\u2500".repeat(50) + "\n"));
|
|
63612
|
+
if (primary) {
|
|
63613
|
+
process.stdout.write(` ${source_default.dim("Primary")} ${makeChalkBar(fivePct, barWidth)} ${String(fivePct).padStart(3)}% ${fiveReset ? source_default.dim("resets " + fiveReset) : ""}
|
|
63614
|
+
`);
|
|
63615
|
+
}
|
|
63616
|
+
if (secondary) {
|
|
63617
|
+
process.stdout.write(` ${source_default.dim("Secondary")} ${makeChalkBar(sevenPct, barWidth - 1)} ${String(sevenPct).padStart(3)}% ${sevenReset ? source_default.dim("resets " + sevenReset) : ""}
|
|
63618
|
+
`);
|
|
63619
|
+
}
|
|
63620
|
+
}
|
|
63461
63621
|
var import_sidekick_shared24;
|
|
63462
63622
|
var init_quota = __esm({
|
|
63463
63623
|
"src/commands/quota.ts"() {
|
|
63464
63624
|
"use strict";
|
|
63465
63625
|
init_source();
|
|
63466
63626
|
import_sidekick_shared24 = __toESM(require_dist(), 1);
|
|
63627
|
+
init_cli();
|
|
63467
63628
|
init_QuotaService();
|
|
63468
63629
|
}
|
|
63469
63630
|
});
|
|
@@ -63473,22 +63634,17 @@ var status_exports = {};
|
|
|
63473
63634
|
__export(status_exports, {
|
|
63474
63635
|
statusAction: () => statusAction
|
|
63475
63636
|
});
|
|
63476
|
-
|
|
63477
|
-
const globalOpts = cmd.parent.opts();
|
|
63478
|
-
const jsonOutput = !!globalOpts.json;
|
|
63479
|
-
const status = await (0, import_sidekick_shared25.fetchProviderStatus)();
|
|
63480
|
-
if (jsonOutput) {
|
|
63481
|
-
process.stdout.write(JSON.stringify(status, null, 2) + "\n");
|
|
63482
|
-
return;
|
|
63483
|
-
}
|
|
63637
|
+
function printStatus(label, statusPageHost, status) {
|
|
63484
63638
|
const indicatorColor = status.indicator === "none" ? source_default.green : status.indicator === "minor" ? source_default.yellow : source_default.red;
|
|
63485
63639
|
const indicatorLabel = status.indicator === "none" ? "\u25CF" : status.indicator === "minor" ? "\u25D0" : "\u25CF";
|
|
63486
|
-
process.stdout.write(source_default.bold(
|
|
63640
|
+
process.stdout.write(source_default.bold(`${label}
|
|
63641
|
+
`));
|
|
63487
63642
|
process.stdout.write(source_default.dim("\u2500".repeat(50) + "\n"));
|
|
63488
63643
|
process.stdout.write(` ${indicatorColor(indicatorLabel)} ${indicatorColor(status.description || status.indicator)}
|
|
63489
63644
|
`);
|
|
63490
63645
|
if (status.description === "Status unavailable") {
|
|
63491
|
-
process.stdout.write(source_default.dim(
|
|
63646
|
+
process.stdout.write(source_default.dim(` Could not reach ${statusPageHost}
|
|
63647
|
+
`));
|
|
63492
63648
|
return;
|
|
63493
63649
|
}
|
|
63494
63650
|
if (status.affectedComponents.length > 0) {
|
|
@@ -63513,6 +63669,21 @@ async function statusAction(_opts, cmd) {
|
|
|
63513
63669
|
}
|
|
63514
63670
|
}
|
|
63515
63671
|
}
|
|
63672
|
+
async function statusAction(_opts, cmd) {
|
|
63673
|
+
const globalOpts = cmd.parent.opts();
|
|
63674
|
+
const jsonOutput = !!globalOpts.json;
|
|
63675
|
+
const [claude, openai] = await Promise.all([
|
|
63676
|
+
(0, import_sidekick_shared25.fetchProviderStatus)(),
|
|
63677
|
+
(0, import_sidekick_shared25.fetchOpenAIStatus)()
|
|
63678
|
+
]);
|
|
63679
|
+
if (jsonOutput) {
|
|
63680
|
+
process.stdout.write(JSON.stringify({ claude, openai }, null, 2) + "\n");
|
|
63681
|
+
return;
|
|
63682
|
+
}
|
|
63683
|
+
printStatus("Claude API Status", "status.claude.com", claude);
|
|
63684
|
+
process.stdout.write("\n");
|
|
63685
|
+
printStatus("OpenAI API Status", "status.openai.com", openai);
|
|
63686
|
+
}
|
|
63516
63687
|
var import_sidekick_shared25;
|
|
63517
63688
|
var init_status = __esm({
|
|
63518
63689
|
"src/commands/status.ts"() {
|
|
@@ -63717,7 +63888,7 @@ var init_cli = __esm({
|
|
|
63717
63888
|
import_sidekick_shared28 = __toESM(require_dist(), 1);
|
|
63718
63889
|
import_sidekick_shared29 = __toESM(require_dist(), 1);
|
|
63719
63890
|
program2 = new Command();
|
|
63720
|
-
program2.name("sidekick").description("Query Sidekick project intelligence from the command line").version("0.
|
|
63891
|
+
program2.name("sidekick").description("Query Sidekick project intelligence from the command line").version("0.15.2").option("--json", "Output as JSON").option("--project <path>", "Override project path (default: cwd)").option("--provider <id>", "Provider: claude-code, opencode, codex, auto (default: auto)");
|
|
63721
63892
|
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) => {
|
|
63722
63893
|
const { dashboardAction: dashboardAction2 } = await init_dashboard().then(() => dashboard_exports);
|
|
63723
63894
|
return dashboardAction2(_opts, cmd);
|
|
@@ -63764,12 +63935,12 @@ var init_cli = __esm({
|
|
|
63764
63935
|
return statsAction2(_opts, cmd);
|
|
63765
63936
|
});
|
|
63766
63937
|
program2.addCommand(statsCmd);
|
|
63767
|
-
quotaCmd = new Command("quota").description("Show
|
|
63938
|
+
quotaCmd = new Command("quota").description("Show quota or rate-limit utilization (auto-detects provider)").option("--provider <id>", "Provider: claude-code, codex, auto (default: auto)").action(async (_opts, cmd) => {
|
|
63768
63939
|
const { quotaAction: quotaAction2 } = await Promise.resolve().then(() => (init_quota(), quota_exports));
|
|
63769
63940
|
return quotaAction2(_opts, cmd);
|
|
63770
63941
|
});
|
|
63771
63942
|
program2.addCommand(quotaCmd);
|
|
63772
|
-
statusCmd = new Command("status").description("Show
|
|
63943
|
+
statusCmd = new Command("status").description("Show API status (Claude and OpenAI)").action(async (_opts, cmd) => {
|
|
63773
63944
|
const { statusAction: statusAction2 } = await Promise.resolve().then(() => (init_status(), status_exports));
|
|
63774
63945
|
return statusAction2(_opts, cmd);
|
|
63775
63946
|
});
|