sidekick-agent-hub 0.18.0 → 0.18.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/sidekick-cli.mjs +404 -183
- package/package.json +1 -1
package/dist/sidekick-cli.mjs
CHANGED
|
@@ -12272,6 +12272,230 @@ var require_eventBridge = __commonJS({
|
|
|
12272
12272
|
}
|
|
12273
12273
|
});
|
|
12274
12274
|
|
|
12275
|
+
// ../sidekick-shared/dist/watchers/jsonlTail.js
|
|
12276
|
+
var require_jsonlTail = __commonJS({
|
|
12277
|
+
"../sidekick-shared/dist/watchers/jsonlTail.js"(exports) {
|
|
12278
|
+
"use strict";
|
|
12279
|
+
var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
|
|
12280
|
+
if (k2 === void 0) k2 = k;
|
|
12281
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12282
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12283
|
+
desc = { enumerable: true, get: function() {
|
|
12284
|
+
return m[k];
|
|
12285
|
+
} };
|
|
12286
|
+
}
|
|
12287
|
+
Object.defineProperty(o, k2, desc);
|
|
12288
|
+
} : function(o, m, k, k2) {
|
|
12289
|
+
if (k2 === void 0) k2 = k;
|
|
12290
|
+
o[k2] = m[k];
|
|
12291
|
+
});
|
|
12292
|
+
var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? function(o, v) {
|
|
12293
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
12294
|
+
} : function(o, v) {
|
|
12295
|
+
o["default"] = v;
|
|
12296
|
+
});
|
|
12297
|
+
var __importStar = exports && exports.__importStar || /* @__PURE__ */ function() {
|
|
12298
|
+
var ownKeys = function(o) {
|
|
12299
|
+
ownKeys = Object.getOwnPropertyNames || function(o2) {
|
|
12300
|
+
var ar = [];
|
|
12301
|
+
for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
|
|
12302
|
+
return ar;
|
|
12303
|
+
};
|
|
12304
|
+
return ownKeys(o);
|
|
12305
|
+
};
|
|
12306
|
+
return function(mod) {
|
|
12307
|
+
if (mod && mod.__esModule) return mod;
|
|
12308
|
+
var result = {};
|
|
12309
|
+
if (mod != null) {
|
|
12310
|
+
for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
12311
|
+
}
|
|
12312
|
+
__setModuleDefault(result, mod);
|
|
12313
|
+
return result;
|
|
12314
|
+
};
|
|
12315
|
+
}();
|
|
12316
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12317
|
+
exports.createJsonlTail = createJsonlTail;
|
|
12318
|
+
var fs9 = __importStar(__require("fs"));
|
|
12319
|
+
var jsonl_1 = require_jsonl();
|
|
12320
|
+
var DEFAULT_DEBOUNCE_MS = 100;
|
|
12321
|
+
var DEFAULT_CATCHUP_INTERVAL_MS = 3e4;
|
|
12322
|
+
function createJsonlTail(options) {
|
|
12323
|
+
return new JsonlTailReader(options);
|
|
12324
|
+
}
|
|
12325
|
+
var JsonlTailReader = class {
|
|
12326
|
+
options;
|
|
12327
|
+
active = false;
|
|
12328
|
+
offset;
|
|
12329
|
+
fsWatcher = null;
|
|
12330
|
+
debounceTimer = null;
|
|
12331
|
+
catchupTimer = null;
|
|
12332
|
+
eventsInCurrentBatch = 0;
|
|
12333
|
+
parser;
|
|
12334
|
+
constructor(options) {
|
|
12335
|
+
this.options = options;
|
|
12336
|
+
this.offset = options.startOffset ?? 0;
|
|
12337
|
+
this.parser = new jsonl_1.JsonlParser({
|
|
12338
|
+
onEvent: (event) => {
|
|
12339
|
+
this.eventsInCurrentBatch += 1;
|
|
12340
|
+
this.options.onEvent(event);
|
|
12341
|
+
},
|
|
12342
|
+
onError: (error, line) => this.options.onError?.(error, line)
|
|
12343
|
+
}, { schema: options.schema });
|
|
12344
|
+
}
|
|
12345
|
+
get isActive() {
|
|
12346
|
+
return this.active;
|
|
12347
|
+
}
|
|
12348
|
+
start() {
|
|
12349
|
+
if (this.active)
|
|
12350
|
+
return;
|
|
12351
|
+
this.active = true;
|
|
12352
|
+
if (this.options.startAtEnd && this.options.startOffset === void 0) {
|
|
12353
|
+
try {
|
|
12354
|
+
this.offset = fs9.statSync(this.options.path).size;
|
|
12355
|
+
} catch {
|
|
12356
|
+
this.offset = 0;
|
|
12357
|
+
}
|
|
12358
|
+
}
|
|
12359
|
+
this.readNow();
|
|
12360
|
+
this.watchFile();
|
|
12361
|
+
const catchupIntervalMs = this.options.catchupIntervalMs ?? DEFAULT_CATCHUP_INTERVAL_MS;
|
|
12362
|
+
if (catchupIntervalMs > 0) {
|
|
12363
|
+
this.catchupTimer = setInterval(() => this.readNow(), catchupIntervalMs);
|
|
12364
|
+
}
|
|
12365
|
+
}
|
|
12366
|
+
stop() {
|
|
12367
|
+
if (!this.active)
|
|
12368
|
+
return;
|
|
12369
|
+
this.active = false;
|
|
12370
|
+
if (this.debounceTimer) {
|
|
12371
|
+
clearTimeout(this.debounceTimer);
|
|
12372
|
+
this.debounceTimer = null;
|
|
12373
|
+
}
|
|
12374
|
+
if (this.fsWatcher) {
|
|
12375
|
+
this.fsWatcher.close();
|
|
12376
|
+
this.fsWatcher = null;
|
|
12377
|
+
}
|
|
12378
|
+
if (this.catchupTimer) {
|
|
12379
|
+
clearInterval(this.catchupTimer);
|
|
12380
|
+
this.catchupTimer = null;
|
|
12381
|
+
}
|
|
12382
|
+
this.parser.flush();
|
|
12383
|
+
}
|
|
12384
|
+
dispose() {
|
|
12385
|
+
this.stop();
|
|
12386
|
+
}
|
|
12387
|
+
readNow() {
|
|
12388
|
+
let fd = null;
|
|
12389
|
+
try {
|
|
12390
|
+
const stat = fs9.statSync(this.options.path);
|
|
12391
|
+
if (stat.size < this.offset) {
|
|
12392
|
+
this.offset = 0;
|
|
12393
|
+
this.parser.reset();
|
|
12394
|
+
}
|
|
12395
|
+
if (stat.size <= this.offset)
|
|
12396
|
+
return;
|
|
12397
|
+
const bytesToRead = stat.size - this.offset;
|
|
12398
|
+
const buffer = Buffer.alloc(bytesToRead);
|
|
12399
|
+
fd = fs9.openSync(this.options.path, "r");
|
|
12400
|
+
const bytesRead = fs9.readSync(fd, buffer, 0, bytesToRead, this.offset);
|
|
12401
|
+
fs9.closeSync(fd);
|
|
12402
|
+
fd = null;
|
|
12403
|
+
if (bytesRead <= 0)
|
|
12404
|
+
return;
|
|
12405
|
+
this.offset += bytesRead;
|
|
12406
|
+
this.eventsInCurrentBatch = 0;
|
|
12407
|
+
this.parser.processChunk(buffer.toString("utf-8", 0, bytesRead));
|
|
12408
|
+
this.options.onBatchComplete?.({
|
|
12409
|
+
bytesRead,
|
|
12410
|
+
eventsRead: this.eventsInCurrentBatch,
|
|
12411
|
+
offset: this.offset
|
|
12412
|
+
});
|
|
12413
|
+
} catch (error) {
|
|
12414
|
+
if (fd !== null) {
|
|
12415
|
+
try {
|
|
12416
|
+
fs9.closeSync(fd);
|
|
12417
|
+
} catch {
|
|
12418
|
+
}
|
|
12419
|
+
}
|
|
12420
|
+
this.options.onError?.(error instanceof Error ? error : new Error(String(error)));
|
|
12421
|
+
}
|
|
12422
|
+
}
|
|
12423
|
+
getOffset() {
|
|
12424
|
+
return this.offset;
|
|
12425
|
+
}
|
|
12426
|
+
seekTo(offset) {
|
|
12427
|
+
this.offset = Math.max(0, offset);
|
|
12428
|
+
this.parser.reset();
|
|
12429
|
+
}
|
|
12430
|
+
watchFile() {
|
|
12431
|
+
try {
|
|
12432
|
+
this.fsWatcher = fs9.watch(this.options.path, { persistent: false }, () => {
|
|
12433
|
+
this.debouncedRead();
|
|
12434
|
+
});
|
|
12435
|
+
this.fsWatcher.on("error", (error) => this.options.onError?.(error));
|
|
12436
|
+
} catch {
|
|
12437
|
+
}
|
|
12438
|
+
}
|
|
12439
|
+
debouncedRead() {
|
|
12440
|
+
if (this.debounceTimer)
|
|
12441
|
+
clearTimeout(this.debounceTimer);
|
|
12442
|
+
const debounceMs = this.options.debounceMs ?? DEFAULT_DEBOUNCE_MS;
|
|
12443
|
+
this.debounceTimer = setTimeout(() => this.readNow(), debounceMs);
|
|
12444
|
+
}
|
|
12445
|
+
};
|
|
12446
|
+
}
|
|
12447
|
+
});
|
|
12448
|
+
|
|
12449
|
+
// ../sidekick-shared/dist/formatting.js
|
|
12450
|
+
var require_formatting = __commonJS({
|
|
12451
|
+
"../sidekick-shared/dist/formatting.js"(exports) {
|
|
12452
|
+
"use strict";
|
|
12453
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12454
|
+
exports.formatTokenCount = formatTokenCount2;
|
|
12455
|
+
exports.formatDurationMs = formatDurationMs2;
|
|
12456
|
+
function formatTokenCount2(value, options = {}) {
|
|
12457
|
+
if (!Number.isFinite(value))
|
|
12458
|
+
return "0";
|
|
12459
|
+
const n = Math.trunc(value);
|
|
12460
|
+
const sign = n < 0 ? "-" : "";
|
|
12461
|
+
const abs = Math.abs(n);
|
|
12462
|
+
const thousandsSuffix = options.suffixCase === "upper" ? "K" : "k";
|
|
12463
|
+
if (abs >= 1e6)
|
|
12464
|
+
return `${sign}${(abs / 1e6).toFixed(1)}M`;
|
|
12465
|
+
if (abs >= 1e3)
|
|
12466
|
+
return `${sign}${(abs / 1e3).toFixed(1)}${thousandsSuffix}`;
|
|
12467
|
+
return `${n}`;
|
|
12468
|
+
}
|
|
12469
|
+
function formatDurationMs2(ms, options = {}) {
|
|
12470
|
+
const invalid = options.invalid ?? "N/A";
|
|
12471
|
+
if (!Number.isFinite(ms) || ms < 0)
|
|
12472
|
+
return invalid;
|
|
12473
|
+
const style = options.style ?? "spaced";
|
|
12474
|
+
const separator = style === "compact" ? "" : " ";
|
|
12475
|
+
const secondsFractionDigits = options.secondsFractionDigits ?? 0;
|
|
12476
|
+
if (ms < 1e3) {
|
|
12477
|
+
if (options.includeMilliseconds)
|
|
12478
|
+
return `${Math.round(ms)}ms`;
|
|
12479
|
+
return `${(ms / 1e3).toFixed(Math.max(1, secondsFractionDigits))}s`;
|
|
12480
|
+
}
|
|
12481
|
+
const seconds = ms / 1e3;
|
|
12482
|
+
if (seconds < 60) {
|
|
12483
|
+
if (secondsFractionDigits > 0)
|
|
12484
|
+
return `${seconds.toFixed(secondsFractionDigits)}s`;
|
|
12485
|
+
return `${Math.floor(seconds)}s`;
|
|
12486
|
+
}
|
|
12487
|
+
const totalSeconds = Math.floor(seconds);
|
|
12488
|
+
const hours = Math.floor(totalSeconds / 3600);
|
|
12489
|
+
const minutes = Math.floor(totalSeconds % 3600 / 60);
|
|
12490
|
+
const remainingSeconds = totalSeconds % 60;
|
|
12491
|
+
if (hours > 0) {
|
|
12492
|
+
return `${hours}h${separator}${minutes}m${separator}${remainingSeconds}s`;
|
|
12493
|
+
}
|
|
12494
|
+
return `${minutes}m${separator}${remainingSeconds}s`;
|
|
12495
|
+
}
|
|
12496
|
+
}
|
|
12497
|
+
});
|
|
12498
|
+
|
|
12275
12499
|
// ../sidekick-shared/dist/formatters/sessionDump.js
|
|
12276
12500
|
var require_sessionDump = __commonJS({
|
|
12277
12501
|
"../sidekick-shared/dist/formatters/sessionDump.js"(exports) {
|
|
@@ -12284,6 +12508,7 @@ var require_sessionDump = __commonJS({
|
|
|
12284
12508
|
exports.fmtCost = fmtCost;
|
|
12285
12509
|
exports.formatTimestamp = formatTimestamp2;
|
|
12286
12510
|
exports.formatDuration = formatDuration2;
|
|
12511
|
+
var formatting_1 = require_formatting();
|
|
12287
12512
|
function formatSessionJson2(metrics) {
|
|
12288
12513
|
return JSON.stringify(metrics, null, 2) + "\n";
|
|
12289
12514
|
}
|
|
@@ -12473,11 +12698,7 @@ var require_sessionDump = __commonJS({
|
|
|
12473
12698
|
return line + ")";
|
|
12474
12699
|
}
|
|
12475
12700
|
function fmtTokens2(n) {
|
|
12476
|
-
|
|
12477
|
-
return `${(n / 1e6).toFixed(1)}M`;
|
|
12478
|
-
if (n >= 1e3)
|
|
12479
|
-
return `${(n / 1e3).toFixed(1)}k`;
|
|
12480
|
-
return String(n);
|
|
12701
|
+
return (0, formatting_1.formatTokenCount)(n);
|
|
12481
12702
|
}
|
|
12482
12703
|
function fmtCost(cost) {
|
|
12483
12704
|
if (cost <= 0)
|
|
@@ -12504,17 +12725,7 @@ var require_sessionDump = __commonJS({
|
|
|
12504
12725
|
return "N/A";
|
|
12505
12726
|
try {
|
|
12506
12727
|
const ms = new Date(end).getTime() - new Date(start).getTime();
|
|
12507
|
-
|
|
12508
|
-
return "N/A";
|
|
12509
|
-
const totalSec = Math.floor(ms / 1e3);
|
|
12510
|
-
const hours = Math.floor(totalSec / 3600);
|
|
12511
|
-
const minutes = Math.floor(totalSec % 3600 / 60);
|
|
12512
|
-
const seconds = totalSec % 60;
|
|
12513
|
-
if (hours > 0)
|
|
12514
|
-
return `${hours}h ${minutes}m ${seconds}s`;
|
|
12515
|
-
if (minutes > 0)
|
|
12516
|
-
return `${minutes}m ${seconds}s`;
|
|
12517
|
-
return `${seconds}s`;
|
|
12728
|
+
return (0, formatting_1.formatDurationMs)(ms);
|
|
12518
12729
|
} catch {
|
|
12519
12730
|
return "N/A";
|
|
12520
12731
|
}
|
|
@@ -35749,9 +35960,9 @@ var require_dist = __commonJS({
|
|
|
35749
35960
|
"use strict";
|
|
35750
35961
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35751
35962
|
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;
|
|
35752
|
-
exports.
|
|
35753
|
-
exports.
|
|
35754
|
-
exports.fetchPeakHoursStatus = exports.fetchOpenAIStatus = exports.fetchProviderStatus = exports.permissionModeSchema = exports.sessionEventSchema = exports.sessionMessageSchema = exports.messageUsageSchema = exports.extractToolCalls = exports.extractToolCall = exports.extractTokenUsage = exports.LITELLM_CATALOG_URL = exports.normalizeLiteLlmCatalog = exports.hydratePricingCatalog = exports.formatCost = exports.sortModelIds = exports.compareModelIds = exports.getModelDisplayInfo = exports.shortModelName = exports.mergeCostSources = exports.calculateCostWithProvenance = exports.calculateCostWithPricing = exports.calculateCost = exports.getModelInfo = exports.getModelPricing = exports.parseModelId = exports.DEFAULT_CONTEXT_WINDOW = void 0;
|
|
35963
|
+
exports.deleteSnapshot = exports.loadSnapshot = exports.saveSnapshot = exports.parseTodoDependencies = exports.EventAggregator = exports.getRandomPhrase = exports.PHRASE_CATEGORIES = 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.formatTokenCount = exports.formatDurationMs = exports.createJsonlTail = 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;
|
|
35964
|
+
exports.quotaFromCodexRateLimits = exports.writeQuotaSnapshot = exports.readQuotaSnapshot = exports.QuotaPoller = exports.describeQuotaFailure = exports.fetchQuota = exports.removeCodexAccount = exports.switchToCodexAccount = exports.finalizeCodexAccount = exports.prepareCodexAccount = exports.getCodexExecutionEnv = exports.resolveSidekickCodexHome = exports.getActiveCodexAccount = exports.listCodexAccounts = exports.getSystemCodexHome = exports.getCodexMonitoringHomes = exports.getCodexProfileHome = exports.getCodexProfilesDir = exports.getActiveAccountStatus = exports.removeSavedAccountProfile = exports.replaceSavedAccountProfiles = exports.setActiveSavedAccount = exports.upsertSavedAccountProfile = exports.getActiveSavedAccount = exports.listSavedAccountProfiles = exports.writeSavedAccountRegistry = exports.readSavedAccountRegistry = exports.getAccountsDir = exports.isMultiAccountEnabled = exports.getActiveAccount = exports.listAccounts = exports.removeAccount = exports.switchToAccount = exports.addCurrentAccount = exports.readActiveClaudeAccount = exports.writeAccountRegistry = exports.readAccountRegistry = exports.ensureDefaultAccounts = exports.readClaudeMaxAccessTokenSync = exports.readClaudeMaxCredentials = exports.writeActiveCredentials = exports.readActiveCredentials = exports.openInBrowser = exports.parseTranscript = exports.generateHtmlReport = exports.PatternExtractor = exports.HeatmapTracker = exports.FrequencyTracker = exports.getSnapshotPath = exports.isSnapshotValid = void 0;
|
|
35965
|
+
exports.fetchPeakHoursStatus = exports.fetchOpenAIStatus = exports.fetchProviderStatus = exports.permissionModeSchema = exports.sessionEventSchema = exports.sessionMessageSchema = exports.messageUsageSchema = exports.extractToolCalls = exports.extractToolCall = exports.extractTokenUsage = exports.LITELLM_CATALOG_URL = exports.normalizeLiteLlmCatalog = exports.hydratePricingCatalog = exports.formatCost = exports.sortModelIds = exports.compareModelIds = exports.getModelDisplayInfo = exports.shortModelName = exports.mergeCostSources = exports.calculateCostWithProvenance = exports.calculateCostWithPricing = exports.calculateCost = exports.getModelInfo = exports.getModelPricing = exports.parseModelId = exports.DEFAULT_CONTEXT_WINDOW = exports.getModelContextWindowSize = exports.MultiProviderQuotaService = exports.CodexQuotaWatcher = void 0;
|
|
35755
35966
|
var taskPersistence_1 = require_taskPersistence();
|
|
35756
35967
|
Object.defineProperty(exports, "TASK_PERSISTENCE_SCHEMA_VERSION", { enumerable: true, get: function() {
|
|
35757
35968
|
return taskPersistence_1.TASK_PERSISTENCE_SCHEMA_VERSION;
|
|
@@ -36010,6 +36221,17 @@ var require_dist = __commonJS({
|
|
|
36010
36221
|
Object.defineProperty(exports, "toFollowEvents", { enumerable: true, get: function() {
|
|
36011
36222
|
return eventBridge_1.toFollowEvents;
|
|
36012
36223
|
} });
|
|
36224
|
+
var jsonlTail_1 = require_jsonlTail();
|
|
36225
|
+
Object.defineProperty(exports, "createJsonlTail", { enumerable: true, get: function() {
|
|
36226
|
+
return jsonlTail_1.createJsonlTail;
|
|
36227
|
+
} });
|
|
36228
|
+
var formatting_1 = require_formatting();
|
|
36229
|
+
Object.defineProperty(exports, "formatDurationMs", { enumerable: true, get: function() {
|
|
36230
|
+
return formatting_1.formatDurationMs;
|
|
36231
|
+
} });
|
|
36232
|
+
Object.defineProperty(exports, "formatTokenCount", { enumerable: true, get: function() {
|
|
36233
|
+
return formatting_1.formatTokenCount;
|
|
36234
|
+
} });
|
|
36013
36235
|
var toolSummary_1 = require_toolSummary();
|
|
36014
36236
|
Object.defineProperty(exports, "formatToolSummary", { enumerable: true, get: function() {
|
|
36015
36237
|
return toolSummary_1.formatToolSummary;
|
|
@@ -38581,7 +38803,7 @@ var init_UpdateCheckService = __esm({
|
|
|
38581
38803
|
/** Run the update check (one-shot). */
|
|
38582
38804
|
async check() {
|
|
38583
38805
|
try {
|
|
38584
|
-
const current = "0.18.
|
|
38806
|
+
const current = "0.18.1";
|
|
38585
38807
|
const cached = this.readCache();
|
|
38586
38808
|
let latest;
|
|
38587
38809
|
if (cached && Date.now() - cached.checkedAt < CACHE_TTL_MS) {
|
|
@@ -38646,17 +38868,14 @@ function shortenPath(p) {
|
|
|
38646
38868
|
return ".../" + parts.slice(-3).join("/");
|
|
38647
38869
|
}
|
|
38648
38870
|
function fmtNum(n) {
|
|
38649
|
-
|
|
38650
|
-
if (n >= 1e3) return `${(n / 1e3).toFixed(1)}K`;
|
|
38651
|
-
return n.toLocaleString();
|
|
38871
|
+
return (0, import_sidekick_shared9.formatTokenCount)(n, { suffixCase: "upper" });
|
|
38652
38872
|
}
|
|
38653
38873
|
function formatDuration(ms) {
|
|
38654
|
-
|
|
38655
|
-
|
|
38656
|
-
|
|
38657
|
-
|
|
38658
|
-
|
|
38659
|
-
return `${mins}m${remSecs}s`;
|
|
38874
|
+
return (0, import_sidekick_shared9.formatDurationMs)(ms, {
|
|
38875
|
+
style: "compact",
|
|
38876
|
+
includeMilliseconds: true,
|
|
38877
|
+
secondsFractionDigits: 1
|
|
38878
|
+
});
|
|
38660
38879
|
}
|
|
38661
38880
|
function stripBlessedTags(text) {
|
|
38662
38881
|
return text.replace(/\{[^}]*\}/g, "");
|
|
@@ -38765,9 +38984,11 @@ function wordWrap(text, width, continuationIndent = "") {
|
|
|
38765
38984
|
return wrapped.map((l, i) => i === 0 ? l : continuationIndent + l).join("\n");
|
|
38766
38985
|
}).join("\n");
|
|
38767
38986
|
}
|
|
38987
|
+
var import_sidekick_shared9;
|
|
38768
38988
|
var init_formatters = __esm({
|
|
38769
38989
|
"src/dashboard/formatters.ts"() {
|
|
38770
38990
|
"use strict";
|
|
38991
|
+
import_sidekick_shared9 = __toESM(require_dist(), 1);
|
|
38771
38992
|
}
|
|
38772
38993
|
});
|
|
38773
38994
|
|
|
@@ -39604,11 +39825,11 @@ function spawnWithStdin(cmd, args, prompt, env3) {
|
|
|
39604
39825
|
proc.stdin.end();
|
|
39605
39826
|
});
|
|
39606
39827
|
}
|
|
39607
|
-
var
|
|
39828
|
+
var import_sidekick_shared10, DEFAULT_ANTHROPIC_MODEL, DEFAULT_OPENAI_MODEL, EXEC_OPTS, CliInferenceClient;
|
|
39608
39829
|
var init_CliInferenceClient = __esm({
|
|
39609
39830
|
"src/inference/CliInferenceClient.ts"() {
|
|
39610
39831
|
"use strict";
|
|
39611
|
-
|
|
39832
|
+
import_sidekick_shared10 = __toESM(require_dist(), 1);
|
|
39612
39833
|
DEFAULT_ANTHROPIC_MODEL = "claude-haiku-4-5-20251001";
|
|
39613
39834
|
DEFAULT_OPENAI_MODEL = "gpt-4o-mini";
|
|
39614
39835
|
EXEC_OPTS = {
|
|
@@ -39756,7 +39977,7 @@ var init_CliInferenceClient = __esm({
|
|
|
39756
39977
|
}
|
|
39757
39978
|
}
|
|
39758
39979
|
completeViaCodexCli(prompt) {
|
|
39759
|
-
return spawnWithStdin("codex", ["exec"], prompt, (0,
|
|
39980
|
+
return spawnWithStdin("codex", ["exec"], prompt, (0, import_sidekick_shared10.getCodexExecutionEnv)());
|
|
39760
39981
|
}
|
|
39761
39982
|
};
|
|
39762
39983
|
}
|
|
@@ -39768,7 +39989,7 @@ function buildNarrativePrompt(metrics, diffStats) {
|
|
|
39768
39989
|
const durationMin = Math.round(durationMs / 6e4);
|
|
39769
39990
|
const t = metrics.tokens;
|
|
39770
39991
|
const totalTokens = t.input + t.output + t.cacheRead + t.cacheWrite;
|
|
39771
|
-
const costStr = (0,
|
|
39992
|
+
const costStr = (0, import_sidekick_shared11.formatCost)(t.cost);
|
|
39772
39993
|
const completed = metrics.tasks.filter((tk) => tk.status === "completed").length;
|
|
39773
39994
|
const completionRate = metrics.tasks.length > 0 ? completed / metrics.tasks.length : 0;
|
|
39774
39995
|
const taskLines = metrics.tasks.length > 0 ? metrics.tasks.map((tk) => ` - "${tk.subject}" (${tk.status}, ${tk.toolCallCount} tool calls)`).join("\n") : " (no tasks tracked)";
|
|
@@ -39797,7 +40018,7 @@ function buildNarrativePrompt(metrics, diffStats) {
|
|
|
39797
40018
|
}
|
|
39798
40019
|
}
|
|
39799
40020
|
const fileSection = fileLines.length > 0 ? fileLines.join("\n") : " (no file changes)";
|
|
39800
|
-
const modelLines = metrics.modelStats.length > 0 ? metrics.modelStats.map((m) => ` - ${m.model}: ${(0,
|
|
40021
|
+
const modelLines = metrics.modelStats.length > 0 ? metrics.modelStats.map((m) => ` - ${m.model}: ${(0, import_sidekick_shared11.formatCost)(m.cost)} (${m.calls} calls, ${fmtNum(m.tokens)} tokens)`).join("\n") : " (no model data)";
|
|
39801
40022
|
const totalToolCalls = metrics.toolStats.reduce((s, ts) => s + ts.calls, 0);
|
|
39802
40023
|
const topTools = metrics.toolStats.slice(0, 5).map((ts) => `${ts.name}(${ts.calls})`).join(", ");
|
|
39803
40024
|
return `You are a helpful assistant summarizing a Claude Code session. Write a concise 2-3 paragraph natural language summary based on this data. Focus on what was accomplished, notable patterns, and any suggestions for future sessions.
|
|
@@ -39824,12 +40045,12 @@ ${modelLines}
|
|
|
39824
40045
|
|
|
39825
40046
|
Write a brief, informative summary in plain English. Do not use bullet points or headers. Be specific about what was accomplished based on the task subjects and file changes.`;
|
|
39826
40047
|
}
|
|
39827
|
-
var
|
|
40048
|
+
var import_sidekick_shared11;
|
|
39828
40049
|
var init_narrativePrompt = __esm({
|
|
39829
40050
|
"src/inference/narrativePrompt.ts"() {
|
|
39830
40051
|
"use strict";
|
|
39831
40052
|
init_formatters();
|
|
39832
|
-
|
|
40053
|
+
import_sidekick_shared11 = __toESM(require_dist(), 1);
|
|
39833
40054
|
}
|
|
39834
40055
|
});
|
|
39835
40056
|
|
|
@@ -39870,17 +40091,17 @@ function renderContextAttribution(attr) {
|
|
|
39870
40091
|
}
|
|
39871
40092
|
return lines;
|
|
39872
40093
|
}
|
|
39873
|
-
var
|
|
40094
|
+
var import_sidekick_shared12, import_sidekick_shared13, MINDMAP_FILTERS, SessionsPanel, EVENT_COLORS;
|
|
39874
40095
|
var init_SessionsPanel = __esm({
|
|
39875
40096
|
"src/dashboard/panels/SessionsPanel.ts"() {
|
|
39876
40097
|
"use strict";
|
|
39877
40098
|
init_formatters();
|
|
39878
|
-
|
|
40099
|
+
import_sidekick_shared12 = __toESM(require_dist(), 1);
|
|
39879
40100
|
init_MindMapBuilder();
|
|
39880
40101
|
init_GitDiffCache();
|
|
39881
40102
|
init_CliInferenceClient();
|
|
39882
40103
|
init_narrativePrompt();
|
|
39883
|
-
|
|
40104
|
+
import_sidekick_shared13 = __toESM(require_dist(), 1);
|
|
39884
40105
|
MINDMAP_FILTERS = ["all", "file", "tool", "task", "subagent", "command", "plan", "knowledge-note"];
|
|
39885
40106
|
SessionsPanel = class {
|
|
39886
40107
|
id = "sessions";
|
|
@@ -40104,7 +40325,7 @@ ${hint}{/grey-fg}`;
|
|
|
40104
40325
|
lines.push(
|
|
40105
40326
|
"",
|
|
40106
40327
|
sectionHeader("Tokens", w2),
|
|
40107
|
-
`{grey-fg}In{/grey-fg} {bold}${fmtNum(t.input)}{/bold} {grey-fg}Out{/grey-fg} {bold}${fmtNum(t.output)}{/bold} ${cacheRate} {green-fg}${(0,
|
|
40328
|
+
`{grey-fg}In{/grey-fg} {bold}${fmtNum(t.input)}{/bold} {grey-fg}Out{/grey-fg} {bold}${fmtNum(t.output)}{/bold} ${cacheRate} {green-fg}${(0, import_sidekick_shared12.formatCost)(t.cost)}{/green-fg}`
|
|
40108
40329
|
);
|
|
40109
40330
|
const contextBar = makeColorBar(c.percent, 30, contextColor);
|
|
40110
40331
|
lines.push(
|
|
@@ -40151,7 +40372,7 @@ ${hint}{/grey-fg}`;
|
|
|
40151
40372
|
lines.push("", sectionHeader("Model Usage", w2));
|
|
40152
40373
|
for (const ms of m.modelStats) {
|
|
40153
40374
|
const modelName = ms.model.length > 20 ? ms.model.substring(0, 17) + "..." : ms.model;
|
|
40154
|
-
const costDisplay = ms.priced === false ? "{yellow-fg}\u2014{/yellow-fg}" : `{green-fg}${(0,
|
|
40375
|
+
const costDisplay = ms.priced === false ? "{yellow-fg}\u2014{/yellow-fg}" : `{green-fg}${(0, import_sidekick_shared12.formatCost)(ms.cost)}{/green-fg}`;
|
|
40155
40376
|
lines.push(` ${modelName.padEnd(20)} {bold}${String(ms.calls).padStart(4)}{/bold}{grey-fg} calls{/grey-fg} ${costDisplay}`);
|
|
40156
40377
|
}
|
|
40157
40378
|
}
|
|
@@ -40174,7 +40395,7 @@ ${hint}{/grey-fg}`;
|
|
|
40174
40395
|
})() : "";
|
|
40175
40396
|
lines.push(` {grey-fg}7d{/grey-fg} ${sevenBar} {bold}${q.sevenDay.utilization.toFixed(0)}%{/bold}${sevenProj}`);
|
|
40176
40397
|
} else if ((m.providerId === "claude-code" || m.providerId === "codex") && m.quota) {
|
|
40177
|
-
const descriptor = (0,
|
|
40398
|
+
const descriptor = (0, import_sidekick_shared13.describeQuotaFailure)(m.quota);
|
|
40178
40399
|
if (descriptor) {
|
|
40179
40400
|
const severityColor = descriptor.severity === "warning" ? "yellow" : descriptor.severity === "info" ? "cyan" : "red";
|
|
40180
40401
|
lines.push("", sectionHeader(quotaLabel, w2));
|
|
@@ -40218,7 +40439,7 @@ ${hint}{/grey-fg}`;
|
|
|
40218
40439
|
const totalTokens = s.inputTokens + s.outputTokens;
|
|
40219
40440
|
return [
|
|
40220
40441
|
`{bold}${s.date}{/bold} {bold}${s.sessionCount}{/bold}{grey-fg} sessions{/grey-fg} {bold}${s.messageCount}{/bold}{grey-fg} messages{/grey-fg}`,
|
|
40221
|
-
`{grey-fg}Tokens{/grey-fg} {bold}${fmtNum(totalTokens)}{/bold} ({grey-fg}In{/grey-fg} ${fmtNum(s.inputTokens)} {grey-fg}Out{/grey-fg} ${fmtNum(s.outputTokens)}) {green-fg}${(0,
|
|
40442
|
+
`{grey-fg}Tokens{/grey-fg} {bold}${fmtNum(totalTokens)}{/bold} ({grey-fg}In{/grey-fg} ${fmtNum(s.inputTokens)} {grey-fg}Out{/grey-fg} ${fmtNum(s.outputTokens)}) {green-fg}${(0, import_sidekick_shared12.formatCost)(s.totalCost)}{/green-fg}`,
|
|
40222
40443
|
"",
|
|
40223
40444
|
sectionHeader("Models", w),
|
|
40224
40445
|
...s.modelUsage.map((u) => ` ${u.model}: {bold}${u.calls}{/bold} calls`),
|
|
@@ -40244,12 +40465,12 @@ ${hint}{/grey-fg}`;
|
|
|
40244
40465
|
let suffix = "";
|
|
40245
40466
|
if (ev.tokens) {
|
|
40246
40467
|
suffix = ` (${fmtNum(ev.tokens.input)} in / ${fmtNum(ev.tokens.output)} out)`;
|
|
40247
|
-
if (ev.cost) suffix += ` ${(0,
|
|
40468
|
+
if (ev.cost) suffix += ` ${(0, import_sidekick_shared12.formatCost)(ev.cost)}`;
|
|
40248
40469
|
}
|
|
40249
40470
|
const prefixLen = 1 + time.length + 2 + 12;
|
|
40250
40471
|
const summaryMax = Math.max(10, w - prefixLen - suffix.length);
|
|
40251
40472
|
const rawSummary = truncate(ev.summary || "", summaryMax);
|
|
40252
|
-
const summary = (0,
|
|
40473
|
+
const summary = (0, import_sidekick_shared13.highlightEvent)(rawSummary, "blessed");
|
|
40253
40474
|
let line = `{${color}-fg}[${time}] ${label}{/${color}-fg} ${summary}`;
|
|
40254
40475
|
if (suffix) {
|
|
40255
40476
|
line += ` {grey-fg}${suffix.trimStart()}{/grey-fg}`;
|
|
@@ -40415,7 +40636,7 @@ function mergeTasks(live, persisted) {
|
|
|
40415
40636
|
map.set(p.taskId, {
|
|
40416
40637
|
taskId: p.taskId,
|
|
40417
40638
|
subject: p.subject,
|
|
40418
|
-
status: (0,
|
|
40639
|
+
status: (0, import_sidekick_shared14.normalizeTaskStatus)(p.status),
|
|
40419
40640
|
blockedBy: p.blockedBy || [],
|
|
40420
40641
|
blocks: p.blocks || [],
|
|
40421
40642
|
subagentType: p.subagentType,
|
|
@@ -40431,11 +40652,11 @@ function mergeTasks(live, persisted) {
|
|
|
40431
40652
|
}
|
|
40432
40653
|
return Array.from(map.values());
|
|
40433
40654
|
}
|
|
40434
|
-
var
|
|
40655
|
+
var import_sidekick_shared14;
|
|
40435
40656
|
var init_taskMerger = __esm({
|
|
40436
40657
|
"src/dashboard/utils/taskMerger.ts"() {
|
|
40437
40658
|
"use strict";
|
|
40438
|
-
|
|
40659
|
+
import_sidekick_shared14 = __toESM(require_dist(), 1);
|
|
40439
40660
|
}
|
|
40440
40661
|
});
|
|
40441
40662
|
|
|
@@ -41038,12 +41259,12 @@ var init_PlansPanel = __esm({
|
|
|
41038
41259
|
});
|
|
41039
41260
|
|
|
41040
41261
|
// src/dashboard/panels/EventStreamPanel.ts
|
|
41041
|
-
var
|
|
41262
|
+
var import_sidekick_shared15, EVENT_TYPE_BADGES, EventStreamPanel;
|
|
41042
41263
|
var init_EventStreamPanel = __esm({
|
|
41043
41264
|
"src/dashboard/panels/EventStreamPanel.ts"() {
|
|
41044
41265
|
"use strict";
|
|
41045
41266
|
init_formatters();
|
|
41046
|
-
|
|
41267
|
+
import_sidekick_shared15 = __toESM(require_dist(), 1);
|
|
41047
41268
|
EVENT_TYPE_BADGES = {
|
|
41048
41269
|
user: "{green-fg}[USR]{/green-fg}",
|
|
41049
41270
|
assistant: "{blue-fg}[AST]{/blue-fg}",
|
|
@@ -41067,7 +41288,7 @@ var init_EventStreamPanel = __esm({
|
|
|
41067
41288
|
return events.map((ev, i) => {
|
|
41068
41289
|
const time = formatTime(ev.timestamp);
|
|
41069
41290
|
const badge = EVENT_TYPE_BADGES[ev.type] || "{grey-fg}[???]{/grey-fg}";
|
|
41070
|
-
const summary = (0,
|
|
41291
|
+
const summary = (0, import_sidekick_shared15.highlightEvent)(ev.summary || "", "blessed");
|
|
41071
41292
|
const label = `{grey-fg}${time}{/grey-fg} ${badge} ${summary}`;
|
|
41072
41293
|
return {
|
|
41073
41294
|
id: `ev-${i}`,
|
|
@@ -41108,7 +41329,7 @@ var init_EventStreamPanel = __esm({
|
|
|
41108
41329
|
lines.push(sectionHeader("Summary", w));
|
|
41109
41330
|
lines.push("");
|
|
41110
41331
|
const summary = String(ev.summary || "(no summary)");
|
|
41111
|
-
lines.push(wordWrap((0,
|
|
41332
|
+
lines.push(wordWrap((0, import_sidekick_shared15.highlightEvent)(summary, "blessed"), w));
|
|
41112
41333
|
lines.push("");
|
|
41113
41334
|
lines.push(sectionHeader("Raw JSON", w));
|
|
41114
41335
|
lines.push("");
|
|
@@ -41137,7 +41358,7 @@ var init_EventStreamPanel = __esm({
|
|
|
41137
41358
|
const ev = events[i];
|
|
41138
41359
|
const time = formatTime(ev.timestamp);
|
|
41139
41360
|
const badge = EVENT_TYPE_BADGES[ev.type] || "{grey-fg}[???]{/grey-fg}";
|
|
41140
|
-
const summary = (0,
|
|
41361
|
+
const summary = (0, import_sidekick_shared15.highlightEvent)(ev.summary || "", "blessed");
|
|
41141
41362
|
if (i === idx) {
|
|
41142
41363
|
lines.push(`{bold}{magenta-fg}\u25B8 ${time} ${badge} ${summary}{/magenta-fg}{/bold}`);
|
|
41143
41364
|
} else {
|
|
@@ -78805,13 +79026,13 @@ var init_SessionPickerInk = __esm({
|
|
|
78805
79026
|
|
|
78806
79027
|
// src/phraseFormatters.ts
|
|
78807
79028
|
function getRandomPhraseBlessedTag() {
|
|
78808
|
-
return `{grey-fg}${(0,
|
|
79029
|
+
return `{grey-fg}${(0, import_sidekick_shared16.getRandomPhrase)()}{/grey-fg}`;
|
|
78809
79030
|
}
|
|
78810
|
-
var
|
|
79031
|
+
var import_sidekick_shared16;
|
|
78811
79032
|
var init_phraseFormatters = __esm({
|
|
78812
79033
|
"src/phraseFormatters.ts"() {
|
|
78813
79034
|
"use strict";
|
|
78814
|
-
|
|
79035
|
+
import_sidekick_shared16 = __toESM(require_dist(), 1);
|
|
78815
79036
|
}
|
|
78816
79037
|
});
|
|
78817
79038
|
|
|
@@ -79199,7 +79420,7 @@ function StatusBar({
|
|
|
79199
79420
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: parseBlessedTags(BRAND_INLINE) }),
|
|
79200
79421
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { dimColor: true, children: [
|
|
79201
79422
|
" v",
|
|
79202
|
-
"0.18.
|
|
79423
|
+
"0.18.1"
|
|
79203
79424
|
] }),
|
|
79204
79425
|
updateInfo && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { color: "yellow", children: [
|
|
79205
79426
|
" (v",
|
|
@@ -79336,7 +79557,7 @@ var init_useSpinner = __esm({
|
|
|
79336
79557
|
// src/dashboard/ink/SplashOverlay.tsx
|
|
79337
79558
|
function SplashOverlay() {
|
|
79338
79559
|
const spinner = useSpinner();
|
|
79339
|
-
const phrase = (0, import_react33.useMemo)(() => (0,
|
|
79560
|
+
const phrase = (0, import_react33.useMemo)(() => (0, import_sidekick_shared17.getRandomPhrase)(), []);
|
|
79340
79561
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
79341
79562
|
Box_default,
|
|
79342
79563
|
{
|
|
@@ -79386,14 +79607,14 @@ function SplashOverlay() {
|
|
|
79386
79607
|
}
|
|
79387
79608
|
);
|
|
79388
79609
|
}
|
|
79389
|
-
var import_react33,
|
|
79610
|
+
var import_react33, import_sidekick_shared17, import_jsx_runtime8;
|
|
79390
79611
|
var init_SplashOverlay = __esm({
|
|
79391
79612
|
async "src/dashboard/ink/SplashOverlay.tsx"() {
|
|
79392
79613
|
"use strict";
|
|
79393
79614
|
import_react33 = __toESM(require_react(), 1);
|
|
79394
79615
|
await init_build2();
|
|
79395
79616
|
init_useSpinner();
|
|
79396
|
-
|
|
79617
|
+
import_sidekick_shared17 = __toESM(require_dist(), 1);
|
|
79397
79618
|
init_branding();
|
|
79398
79619
|
await init_parseBlessedTags();
|
|
79399
79620
|
import_jsx_runtime8 = __toESM(require_jsx_runtime(), 1);
|
|
@@ -79589,7 +79810,7 @@ function ChangelogOverlay({ entries, scrollOffset }) {
|
|
|
79589
79810
|
" ",
|
|
79590
79811
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Text, { bold: true, color: "cyan", children: [
|
|
79591
79812
|
"Terminal Dashboard v",
|
|
79592
|
-
"0.18.
|
|
79813
|
+
"0.18.1"
|
|
79593
79814
|
] }),
|
|
79594
79815
|
latestDate ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Text, { color: "gray", children: [
|
|
79595
79816
|
" \u2014 ",
|
|
@@ -79911,7 +80132,7 @@ var init_mouse = __esm({
|
|
|
79911
80132
|
var CHANGELOG_default;
|
|
79912
80133
|
var init_CHANGELOG = __esm({
|
|
79913
80134
|
"CHANGELOG.md"() {
|
|
79914
|
-
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.18.0] - 2026-05-08\n\n### Changed\n\n- **Bundled `sidekick-shared` 0.18.0**: Picks up the new provider-aware quota orchestration surface \u2014 `MultiProviderQuotaService`, `CodexQuotaWatcher`, `getActiveAccountStatus()`, `extractToolCall()`, cost-provenance helpers (`calculateCostWithProvenance`, `mergeCostSources`), and model display helpers (`shortModelName`, `getModelDisplayInfo`, `compareModelIds`, `sortModelIds`). `parseModelId()` also now recognizes legacy Claude IDs such as `claude-3-opus-20240229` and `claude-3-5-sonnet-20241022`\n- **No CLI runtime changes**: This release ships the shared library upgrade for downstream tooling alignment; `sidekick quota`, `sidekick status`, and the live dashboard keep using the existing polling path. Wiring the new orchestrator into the CLI will land in a follow-up release\n\n## [0.17.7] - 2026-04-28\n\n### Fixed\n\n- **Quota snapshot write race**: Updated the bundled `sidekick-shared` snapshot writer so concurrent `sidekick quota` / Codex session updates no longer collide on `quota-snapshots.json.tmp` or throw `ENOENT`. Failed writes now also clean up their partial temp files instead of leaving orphans in `~/.config/sidekick/`\n\n## [0.17.6] - 2026-04-19\n\n### Added\n\n- **`sidekick peak` command**: One-shot check for Claude\'s current peak-hours state \u2014 weekdays 13:00\u201319:00 UTC, when session limits drain faster on Free/Pro/Max/Team subscriptions. Prints a color-coded status block with a countdown to the next transition. Data comes from the public `promoclock.co/api/status` endpoint (third-party, unaffiliated with Anthropic) with a graceful fallback when unreachable. `--json` emits the full raw state\n- **Peak-hours block in `sidekick status`**: When the active provider is `claude-code`, the Claude + OpenAI health blocks are now followed by a **Claude Peak Hours** block (off-peak or in-peak, with countdown). Gated on the provider so OpenCode / Codex users don\'t trigger an unnecessary third-party fetch. `--json` output includes the new `peak` field\n- **Peak-hours summary in `sidekick quota`**: Claude subscription quota output now shows a **Peak** line under the 5-hour / 7-day bars \u2014 green dot off-peak, orange dot during an active peak, with a countdown to the next transition. `--json` output includes the new `peak` field\n\n## [0.17.5] - 2026-04-18\n\n### Added\n\n- **Default account bootstrap at CLI startup**: The CLI now calls `ensureDefaultAccounts()` from `sidekick-shared` at module load and awaits the result inside a Commander `preAction` hook, so the first real subcommand blocks briefly on the bootstrap while `--version` and `--help` stay instant. When a system Claude Code or Codex credential exists and no saved account is active for that provider yet, the CLI registers it as "Default" \u2014 `sidekick quota`, `sidekick account`, and `sidekick stats` now reflect the active account on first run without requiring an explicit `sidekick account --add` first. Idempotent, never overwrites manually saved accounts, and all errors are swallowed so startup is never blocked\n\nThanks to [@B33pBeeps](https://github.com/B33pBeeps) (Juan Fourie) for contributing this feature in [#16](https://github.com/cesarandreslopez/sidekick-agent-hub/pull/16).\n\n## [0.17.4] - 2026-04-17\n\n### Changed\n\n- **Pricing hydration import migrated to `sidekick-shared/node`**: `cli.ts` now imports `hydratePricingCatalog` from the new Node-only subpath and keeps `detectProvider` on the package root. Runtime behavior is unchanged; the split makes the CLI\'s import surface self-documenting (hydration is explicitly a Node API) and aligns the CLI with the shared library\'s new versioned public API contract\n\n## [0.17.3] - 2026-04-17\n\n### Changed\n\n- **Version sync with the VS Code extension**: Republished to keep CLI, extension, and shared-library versions aligned after a cosmetic changelog fix in 0.17.3. No CLI code changes \u2014 functionally identical to 0.17.2\n\n## [0.17.2] - 2026-04-17\n\n### Added\n\n- **LiteLLM pricing hydration on startup**: The CLI now fetches the LiteLLM pricing catalog on startup and caches to `~/.config/sidekick/pricing-catalog.json` with a 24-hour TTL, 3s timeout, and stale-cache fallback \u2014 new model prices are picked up without a CLI upgrade\n- **Expanded pricing coverage**: GPT-4o, GPT-4.1, GPT-5.x, o1, o3, and o3-mini families are now priced alongside the existing Claude entries\n- **Real-dollar Codex / Claude Code costs**: `EventAggregator` computes cost from the pricing table when the session provider doesn\'t report one, so `sidekick` live dashboards now show actual dollars for Codex and Claude Code sessions\n- **`stats` footer lists unpriced models**: `sidekick stats` prints any models encountered with no pricing entry so missing coverage is visible\n\n### Fixed\n\n- **Context-gauge % wrong for Opus 4.7 (1M) and other new models**: The dashboard\'s context gauge was dividing by 200K for Claude Opus 4.7 (native 1M), inflating the displayed %. The shared model \u2192 context-window map now includes Opus/Sonnet 4.7 (1M), GPT-5.4 (1.05M), GPT-5.3-Codex (400K), and GPT-5.3-Codex-Spark (128K). Claude Code\'s `[1m]` suffix is now also honored as an explicit 1M marker\n- **Silent Sonnet-priced fallback for unknown models**: Codex, GPT-5.x, and o-series rows were being rendered at Sonnet rates. Unknown-model rows now render as `\u2014` in yellow instead of inventing a dollar figure\n\n### Changed\n\n- **`historical-data.json` schema v2**: reads `priced` flag and `unpricedModelIds` from records written by the latest VS Code extension; v1 records still read correctly\n\n## [0.17.1] - 2026-04-13\n\n### Fixed\n\n- **Codex multi-home session discovery**: Provider detection now scans all candidate Codex home directories, fixing missed sessions when the managed profile home is empty but the system `~/.codex/` has activity\n\n## [0.17.0] - 2026-04-13\n\n### Added\n\n- **Multi-provider account management**: `sidekick account` now supports `--provider codex` for Codex profile management alongside Claude Code accounts\n- **Codex account lifecycle**: `--add` prepares a profile and spawns `codex login`; `--switch-to` and `--remove` accept email, label, or profile ID\n- **Quota snapshot fallback**: `sidekick quota` for Codex shows cached rate-limit snapshots when no active session exists, with "cached from" timestamp\n\n### Fixed\n\n- **Email normalization**: Claude account lookup normalizes email case for reliable matching\n\n## [0.16.1] - 2026-03-27\n\n### Fixed\n\n- **Dashboard provider status scoping**: The TUI now shows degraded-service notices only for the monitored provider \u2014 Claude for Claude Code sessions, OpenAI for Codex sessions, and no status banner for OpenCode\n\n## [0.16.0] - 2026-03-23\n\n### Changed\n\n- **Consistent cost formatting**: All cost displays (`stats`, `context`, Sessions panel, narrative prompt) now use shared `formatCost()` with intelligent decimal precision (4 places for < $0.01, 2 otherwise)\n- **QuotaService**: Rewritten to wrap shared `QuotaPoller` with exponential backoff instead of manual polling loop\n- **modelContext**: Now re-exports `getModelInfo` from shared library alongside `getContextWindowSize`\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';
|
|
80135
|
+
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.18.1] - 2026-05-08\n\n### Changed\n\n- **Shared dashboard formatting**: terminal dashboard `fmtNum()` and `formatDuration()` now delegate to `formatTokenCount()` and `formatDurationMs()` from `sidekick-shared`, keeping the existing CLI surface (uppercase `K`/`M` suffix, compact `1m5s` style) while removing forked rounding logic\n\n## [0.18.0] - 2026-05-08\n\n### Changed\n\n- **Bundled `sidekick-shared` 0.18.0**: Picks up the new provider-aware quota orchestration surface \u2014 `MultiProviderQuotaService`, `CodexQuotaWatcher`, `getActiveAccountStatus()`, `extractToolCall()`, cost-provenance helpers (`calculateCostWithProvenance`, `mergeCostSources`), and model display helpers (`shortModelName`, `getModelDisplayInfo`, `compareModelIds`, `sortModelIds`). `parseModelId()` also now recognizes legacy Claude IDs such as `claude-3-opus-20240229` and `claude-3-5-sonnet-20241022`\n- **No CLI runtime changes**: This release ships the shared library upgrade for downstream tooling alignment; `sidekick quota`, `sidekick status`, and the live dashboard keep using the existing polling path. Wiring the new orchestrator into the CLI will land in a follow-up release\n\n## [0.17.7] - 2026-04-28\n\n### Fixed\n\n- **Quota snapshot write race**: Updated the bundled `sidekick-shared` snapshot writer so concurrent `sidekick quota` / Codex session updates no longer collide on `quota-snapshots.json.tmp` or throw `ENOENT`. Failed writes now also clean up their partial temp files instead of leaving orphans in `~/.config/sidekick/`\n\n## [0.17.6] - 2026-04-19\n\n### Added\n\n- **`sidekick peak` command**: One-shot check for Claude\'s current peak-hours state \u2014 weekdays 13:00\u201319:00 UTC, when session limits drain faster on Free/Pro/Max/Team subscriptions. Prints a color-coded status block with a countdown to the next transition. Data comes from the public `promoclock.co/api/status` endpoint (third-party, unaffiliated with Anthropic) with a graceful fallback when unreachable. `--json` emits the full raw state\n- **Peak-hours block in `sidekick status`**: When the active provider is `claude-code`, the Claude + OpenAI health blocks are now followed by a **Claude Peak Hours** block (off-peak or in-peak, with countdown). Gated on the provider so OpenCode / Codex users don\'t trigger an unnecessary third-party fetch. `--json` output includes the new `peak` field\n- **Peak-hours summary in `sidekick quota`**: Claude subscription quota output now shows a **Peak** line under the 5-hour / 7-day bars \u2014 green dot off-peak, orange dot during an active peak, with a countdown to the next transition. `--json` output includes the new `peak` field\n\n## [0.17.5] - 2026-04-18\n\n### Added\n\n- **Default account bootstrap at CLI startup**: The CLI now calls `ensureDefaultAccounts()` from `sidekick-shared` at module load and awaits the result inside a Commander `preAction` hook, so the first real subcommand blocks briefly on the bootstrap while `--version` and `--help` stay instant. When a system Claude Code or Codex credential exists and no saved account is active for that provider yet, the CLI registers it as "Default" \u2014 `sidekick quota`, `sidekick account`, and `sidekick stats` now reflect the active account on first run without requiring an explicit `sidekick account --add` first. Idempotent, never overwrites manually saved accounts, and all errors are swallowed so startup is never blocked\n\nThanks to [@B33pBeeps](https://github.com/B33pBeeps) (Juan Fourie) for contributing this feature in [#16](https://github.com/cesarandreslopez/sidekick-agent-hub/pull/16).\n\n## [0.17.4] - 2026-04-17\n\n### Changed\n\n- **Pricing hydration import migrated to `sidekick-shared/node`**: `cli.ts` now imports `hydratePricingCatalog` from the new Node-only subpath and keeps `detectProvider` on the package root. Runtime behavior is unchanged; the split makes the CLI\'s import surface self-documenting (hydration is explicitly a Node API) and aligns the CLI with the shared library\'s new versioned public API contract\n\n## [0.17.3] - 2026-04-17\n\n### Changed\n\n- **Version sync with the VS Code extension**: Republished to keep CLI, extension, and shared-library versions aligned after a cosmetic changelog fix in 0.17.3. No CLI code changes \u2014 functionally identical to 0.17.2\n\n## [0.17.2] - 2026-04-17\n\n### Added\n\n- **LiteLLM pricing hydration on startup**: The CLI now fetches the LiteLLM pricing catalog on startup and caches to `~/.config/sidekick/pricing-catalog.json` with a 24-hour TTL, 3s timeout, and stale-cache fallback \u2014 new model prices are picked up without a CLI upgrade\n- **Expanded pricing coverage**: GPT-4o, GPT-4.1, GPT-5.x, o1, o3, and o3-mini families are now priced alongside the existing Claude entries\n- **Real-dollar Codex / Claude Code costs**: `EventAggregator` computes cost from the pricing table when the session provider doesn\'t report one, so `sidekick` live dashboards now show actual dollars for Codex and Claude Code sessions\n- **`stats` footer lists unpriced models**: `sidekick stats` prints any models encountered with no pricing entry so missing coverage is visible\n\n### Fixed\n\n- **Context-gauge % wrong for Opus 4.7 (1M) and other new models**: The dashboard\'s context gauge was dividing by 200K for Claude Opus 4.7 (native 1M), inflating the displayed %. The shared model \u2192 context-window map now includes Opus/Sonnet 4.7 (1M), GPT-5.4 (1.05M), GPT-5.3-Codex (400K), and GPT-5.3-Codex-Spark (128K). Claude Code\'s `[1m]` suffix is now also honored as an explicit 1M marker\n- **Silent Sonnet-priced fallback for unknown models**: Codex, GPT-5.x, and o-series rows were being rendered at Sonnet rates. Unknown-model rows now render as `\u2014` in yellow instead of inventing a dollar figure\n\n### Changed\n\n- **`historical-data.json` schema v2**: reads `priced` flag and `unpricedModelIds` from records written by the latest VS Code extension; v1 records still read correctly\n\n## [0.17.1] - 2026-04-13\n\n### Fixed\n\n- **Codex multi-home session discovery**: Provider detection now scans all candidate Codex home directories, fixing missed sessions when the managed profile home is empty but the system `~/.codex/` has activity\n\n## [0.17.0] - 2026-04-13\n\n### Added\n\n- **Multi-provider account management**: `sidekick account` now supports `--provider codex` for Codex profile management alongside Claude Code accounts\n- **Codex account lifecycle**: `--add` prepares a profile and spawns `codex login`; `--switch-to` and `--remove` accept email, label, or profile ID\n- **Quota snapshot fallback**: `sidekick quota` for Codex shows cached rate-limit snapshots when no active session exists, with "cached from" timestamp\n\n### Fixed\n\n- **Email normalization**: Claude account lookup normalizes email case for reliable matching\n\n## [0.16.1] - 2026-03-27\n\n### Fixed\n\n- **Dashboard provider status scoping**: The TUI now shows degraded-service notices only for the monitored provider \u2014 Claude for Claude Code sessions, OpenAI for Codex sessions, and no status banner for OpenCode\n\n## [0.16.0] - 2026-03-23\n\n### Changed\n\n- **Consistent cost formatting**: All cost displays (`stats`, `context`, Sessions panel, narrative prompt) now use shared `formatCost()` with intelligent decimal precision (4 places for < $0.01, 2 otherwise)\n- **QuotaService**: Rewritten to wrap shared `QuotaPoller` with exponential backoff instead of manual polling loop\n- **modelContext**: Now re-exports `getModelInfo` from shared library alongside `getContextWindowSize`\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';
|
|
79915
80136
|
}
|
|
79916
80137
|
});
|
|
79917
80138
|
|
|
@@ -80080,7 +80301,7 @@ function Dashboard({ panels, metrics, staticData, isPinned, pendingSessionPath,
|
|
|
80080
80301
|
lastQuotaAlertKeyRef.current = null;
|
|
80081
80302
|
return;
|
|
80082
80303
|
}
|
|
80083
|
-
const descriptor = (0,
|
|
80304
|
+
const descriptor = (0, import_sidekick_shared18.describeQuotaFailure)(metrics.quota);
|
|
80084
80305
|
if (!descriptor) {
|
|
80085
80306
|
lastQuotaAlertKeyRef.current = null;
|
|
80086
80307
|
return;
|
|
@@ -80656,7 +80877,7 @@ function filterKanbanColumn(item, filter) {
|
|
|
80656
80877
|
data: { status: colData.status, tasks: filtered }
|
|
80657
80878
|
};
|
|
80658
80879
|
}
|
|
80659
|
-
var import_react36,
|
|
80880
|
+
var import_react36, import_sidekick_shared18, import_jsx_runtime16, changelogEntries, SIDE_PANEL_WIDTH, NARROW_SIDE_WIDTH, MIN_SCREEN_WIDTH, MIN_SCREEN_HEIGHT, WIDE_SIDE_WIDTH, initialState;
|
|
80660
80881
|
var init_Dashboard = __esm({
|
|
80661
80882
|
async "src/dashboard/ink/Dashboard.tsx"() {
|
|
80662
80883
|
"use strict";
|
|
@@ -80679,9 +80900,9 @@ var init_Dashboard = __esm({
|
|
|
80679
80900
|
await init_ToastNotification();
|
|
80680
80901
|
await init_mouse();
|
|
80681
80902
|
init_CHANGELOG();
|
|
80682
|
-
|
|
80903
|
+
import_sidekick_shared18 = __toESM(require_dist(), 1);
|
|
80683
80904
|
import_jsx_runtime16 = __toESM(require_jsx_runtime(), 1);
|
|
80684
|
-
changelogEntries = (0,
|
|
80905
|
+
changelogEntries = (0, import_sidekick_shared18.parseChangelog)(CHANGELOG_default, 5);
|
|
80685
80906
|
SIDE_PANEL_WIDTH = 26;
|
|
80686
80907
|
NARROW_SIDE_WIDTH = 22;
|
|
80687
80908
|
MIN_SCREEN_WIDTH = 60;
|
|
@@ -80720,12 +80941,12 @@ import * as fs6 from "fs";
|
|
|
80720
80941
|
function createProviderById(id) {
|
|
80721
80942
|
switch (id) {
|
|
80722
80943
|
case "opencode":
|
|
80723
|
-
return new
|
|
80944
|
+
return new import_sidekick_shared20.OpenCodeProvider();
|
|
80724
80945
|
case "codex":
|
|
80725
|
-
return new
|
|
80946
|
+
return new import_sidekick_shared20.CodexProvider();
|
|
80726
80947
|
case "claude-code":
|
|
80727
80948
|
default:
|
|
80728
|
-
return new
|
|
80949
|
+
return new import_sidekick_shared20.ClaudeCodeProvider();
|
|
80729
80950
|
}
|
|
80730
80951
|
}
|
|
80731
80952
|
function getProviderRuntimeIssue(provider) {
|
|
@@ -80749,7 +80970,7 @@ async function dashboardAction(_opts, cmd) {
|
|
|
80749
80970
|
let replay = !!opts.replay;
|
|
80750
80971
|
let activeProvider = provider;
|
|
80751
80972
|
const providerIssue = getProviderRuntimeIssue(provider);
|
|
80752
|
-
const detectedIds = (0,
|
|
80973
|
+
const detectedIds = (0, import_sidekick_shared19.getAllDetectedProviders)();
|
|
80753
80974
|
const additionalProviders = detectedIds.filter((id) => id !== provider.id).map((id) => createProviderById(id));
|
|
80754
80975
|
if (!sessionId) {
|
|
80755
80976
|
const sessions = providerIssue ? [] : provider.findAllSessions(workspacePath);
|
|
@@ -80847,7 +81068,7 @@ async function dashboardAction(_opts, cmd) {
|
|
|
80847
81068
|
const newSessionId = path4.basename(newSessionPath, path4.extname(newSessionPath));
|
|
80848
81069
|
state.setSessionId(newSessionId);
|
|
80849
81070
|
try {
|
|
80850
|
-
const result = (0,
|
|
81071
|
+
const result = (0, import_sidekick_shared19.createWatcher)({
|
|
80851
81072
|
provider: activeProvider,
|
|
80852
81073
|
workspacePath,
|
|
80853
81074
|
sessionId: newSessionId,
|
|
@@ -80922,7 +81143,7 @@ async function dashboardAction(_opts, cmd) {
|
|
|
80922
81143
|
const generateReport = () => {
|
|
80923
81144
|
if (!sessionPath) return;
|
|
80924
81145
|
const events = [];
|
|
80925
|
-
const replayResult = (0,
|
|
81146
|
+
const replayResult = (0, import_sidekick_shared19.createWatcher)({
|
|
80926
81147
|
provider: activeProvider,
|
|
80927
81148
|
workspacePath,
|
|
80928
81149
|
sessionId: path4.basename(sessionPath, path4.extname(sessionPath)),
|
|
@@ -80931,11 +81152,11 @@ async function dashboardAction(_opts, cmd) {
|
|
|
80931
81152
|
});
|
|
80932
81153
|
replayResult.watcher.start(true);
|
|
80933
81154
|
replayResult.watcher.stop();
|
|
80934
|
-
const aggregator = new
|
|
81155
|
+
const aggregator = new import_sidekick_shared19.EventAggregator({ providerId: activeProvider.id });
|
|
80935
81156
|
for (const e of events) aggregator.processFollowEvent(e);
|
|
80936
81157
|
const metrics = aggregator.getMetrics();
|
|
80937
|
-
const transcript = (0,
|
|
80938
|
-
const html = (0,
|
|
81158
|
+
const transcript = (0, import_sidekick_shared19.parseTranscript)(sessionPath);
|
|
81159
|
+
const html = (0, import_sidekick_shared19.generateHtmlReport)(metrics, transcript, {
|
|
80939
81160
|
sessionFileName: path4.basename(sessionPath),
|
|
80940
81161
|
includeThinking: true,
|
|
80941
81162
|
includeToolDetail: true,
|
|
@@ -80943,7 +81164,7 @@ async function dashboardAction(_opts, cmd) {
|
|
|
80943
81164
|
});
|
|
80944
81165
|
const outFile = path4.join(os3.tmpdir(), `sidekick-report-${Date.now()}.html`);
|
|
80945
81166
|
fs6.writeFileSync(outFile, html, "utf-8");
|
|
80946
|
-
(0,
|
|
81167
|
+
(0, import_sidekick_shared19.openInBrowser)(outFile);
|
|
80947
81168
|
};
|
|
80948
81169
|
const instance = render2(
|
|
80949
81170
|
import_react37.default.createElement(Dashboard, {
|
|
@@ -81041,7 +81262,7 @@ async function dashboardAction(_opts, cmd) {
|
|
|
81041
81262
|
let lastSnapshotTime = 0;
|
|
81042
81263
|
const SNAPSHOT_INTERVAL_MS = 3e4;
|
|
81043
81264
|
try {
|
|
81044
|
-
const result = (0,
|
|
81265
|
+
const result = (0, import_sidekick_shared19.createWatcher)({
|
|
81045
81266
|
provider: activeProvider,
|
|
81046
81267
|
workspacePath,
|
|
81047
81268
|
sessionId,
|
|
@@ -81116,13 +81337,13 @@ async function dashboardAction(_opts, cmd) {
|
|
|
81116
81337
|
cleanup();
|
|
81117
81338
|
process.exit(0);
|
|
81118
81339
|
}
|
|
81119
|
-
var import_react37,
|
|
81340
|
+
var import_react37, import_sidekick_shared19, import_sidekick_shared20;
|
|
81120
81341
|
var init_dashboard = __esm({
|
|
81121
81342
|
async "src/commands/dashboard.ts"() {
|
|
81122
81343
|
"use strict";
|
|
81123
81344
|
import_react37 = __toESM(require_react(), 1);
|
|
81124
|
-
import_sidekick_shared18 = __toESM(require_dist(), 1);
|
|
81125
81345
|
import_sidekick_shared19 = __toESM(require_dist(), 1);
|
|
81346
|
+
import_sidekick_shared20 = __toESM(require_dist(), 1);
|
|
81126
81347
|
init_cli();
|
|
81127
81348
|
init_DashboardState();
|
|
81128
81349
|
init_StaticDataLoader();
|
|
@@ -81253,7 +81474,7 @@ async function dumpAction(_opts, cmd) {
|
|
|
81253
81474
|
let sessionPath;
|
|
81254
81475
|
try {
|
|
81255
81476
|
try {
|
|
81256
|
-
const result = (0,
|
|
81477
|
+
const result = (0, import_sidekick_shared21.createWatcher)({
|
|
81257
81478
|
provider,
|
|
81258
81479
|
workspacePath,
|
|
81259
81480
|
sessionId,
|
|
@@ -81274,7 +81495,7 @@ async function dumpAction(_opts, cmd) {
|
|
|
81274
81495
|
`);
|
|
81275
81496
|
process.exit(1);
|
|
81276
81497
|
}
|
|
81277
|
-
const aggregator = new
|
|
81498
|
+
const aggregator = new import_sidekick_shared21.EventAggregator({ providerId: provider.id });
|
|
81278
81499
|
for (const event of events) {
|
|
81279
81500
|
aggregator.processFollowEvent(event);
|
|
81280
81501
|
}
|
|
@@ -81282,14 +81503,14 @@ async function dumpAction(_opts, cmd) {
|
|
|
81282
81503
|
const sessionFileName = path5.basename(sessionPath);
|
|
81283
81504
|
switch (format) {
|
|
81284
81505
|
case "json":
|
|
81285
|
-
process.stdout.write((0,
|
|
81506
|
+
process.stdout.write((0, import_sidekick_shared21.formatSessionJson)(metrics));
|
|
81286
81507
|
break;
|
|
81287
81508
|
case "markdown":
|
|
81288
|
-
process.stdout.write((0,
|
|
81509
|
+
process.stdout.write((0, import_sidekick_shared21.formatSessionMarkdown)(metrics, { expand, sessionFileName }));
|
|
81289
81510
|
break;
|
|
81290
81511
|
case "text":
|
|
81291
81512
|
default:
|
|
81292
|
-
process.stdout.write((0,
|
|
81513
|
+
process.stdout.write((0, import_sidekick_shared21.formatSessionText)(metrics, { width: termWidth, expand }));
|
|
81293
81514
|
break;
|
|
81294
81515
|
}
|
|
81295
81516
|
} finally {
|
|
@@ -81299,11 +81520,11 @@ async function dumpAction(_opts, cmd) {
|
|
|
81299
81520
|
}
|
|
81300
81521
|
}
|
|
81301
81522
|
}
|
|
81302
|
-
var
|
|
81523
|
+
var import_sidekick_shared21;
|
|
81303
81524
|
var init_dump = __esm({
|
|
81304
81525
|
"src/commands/dump.ts"() {
|
|
81305
81526
|
"use strict";
|
|
81306
|
-
|
|
81527
|
+
import_sidekick_shared21 = __toESM(require_dist(), 1);
|
|
81307
81528
|
init_cli();
|
|
81308
81529
|
}
|
|
81309
81530
|
});
|
|
@@ -81373,7 +81594,7 @@ function formatContextText(ctx, slug) {
|
|
|
81373
81594
|
const t = ctx.stats.tokens;
|
|
81374
81595
|
lines.push(`Tokens: ${t.inputTokens.toLocaleString()} in / ${t.outputTokens.toLocaleString()} out`);
|
|
81375
81596
|
lines.push(`Cache: ${t.cacheReadTokens.toLocaleString()} read / ${t.cacheWriteTokens.toLocaleString()} write`);
|
|
81376
|
-
lines.push(`Cost: ${(0,
|
|
81597
|
+
lines.push(`Cost: ${(0, import_sidekick_shared22.formatCost)(ctx.stats.cost)}`);
|
|
81377
81598
|
lines.push("");
|
|
81378
81599
|
}
|
|
81379
81600
|
if (ctx.sessionSummaries.length > 0) {
|
|
@@ -81393,11 +81614,11 @@ async function contextAction(_opts, cmd) {
|
|
|
81393
81614
|
const workspacePath = globalOpts.project || process.cwd();
|
|
81394
81615
|
const jsonOutput = !!globalOpts.json || !!opts.json;
|
|
81395
81616
|
const fidelity = opts.fidelity || "full";
|
|
81396
|
-
const slug = (0,
|
|
81397
|
-
const slugRaw = (0,
|
|
81617
|
+
const slug = (0, import_sidekick_shared22.getProjectSlug)(workspacePath);
|
|
81618
|
+
const slugRaw = (0, import_sidekick_shared22.getProjectSlugRaw)(workspacePath);
|
|
81398
81619
|
const effectiveSlug = slug !== slugRaw ? slugRaw : slug;
|
|
81399
81620
|
try {
|
|
81400
|
-
const ctx = await (0,
|
|
81621
|
+
const ctx = await (0, import_sidekick_shared22.composeContext)(effectiveSlug, fidelity, provider, workspacePath);
|
|
81401
81622
|
if (jsonOutput) {
|
|
81402
81623
|
process.stdout.write(JSON.stringify(ctx, null, 2) + "\n");
|
|
81403
81624
|
} else {
|
|
@@ -81415,11 +81636,11 @@ async function contextAction(_opts, cmd) {
|
|
|
81415
81636
|
}
|
|
81416
81637
|
}
|
|
81417
81638
|
}
|
|
81418
|
-
var
|
|
81639
|
+
var import_sidekick_shared22;
|
|
81419
81640
|
var init_context = __esm({
|
|
81420
81641
|
"src/commands/context.ts"() {
|
|
81421
81642
|
"use strict";
|
|
81422
|
-
|
|
81643
|
+
import_sidekick_shared22 = __toESM(require_dist(), 1);
|
|
81423
81644
|
init_cli();
|
|
81424
81645
|
}
|
|
81425
81646
|
});
|
|
@@ -81446,7 +81667,7 @@ async function reportAction(_opts, cmd) {
|
|
|
81446
81667
|
let sessionPath;
|
|
81447
81668
|
try {
|
|
81448
81669
|
try {
|
|
81449
|
-
const result = (0,
|
|
81670
|
+
const result = (0, import_sidekick_shared23.createWatcher)({
|
|
81450
81671
|
provider,
|
|
81451
81672
|
workspacePath,
|
|
81452
81673
|
sessionId,
|
|
@@ -81467,12 +81688,12 @@ async function reportAction(_opts, cmd) {
|
|
|
81467
81688
|
`);
|
|
81468
81689
|
process.exit(1);
|
|
81469
81690
|
}
|
|
81470
|
-
const aggregator = new
|
|
81691
|
+
const aggregator = new import_sidekick_shared23.EventAggregator({ providerId: provider.id });
|
|
81471
81692
|
for (const event of events) {
|
|
81472
81693
|
aggregator.processFollowEvent(event);
|
|
81473
81694
|
}
|
|
81474
81695
|
const metrics = aggregator.getMetrics();
|
|
81475
|
-
const transcript = (0,
|
|
81696
|
+
const transcript = (0, import_sidekick_shared23.parseTranscript)(sessionPath);
|
|
81476
81697
|
const sessionFileName = path6.basename(sessionPath);
|
|
81477
81698
|
const reportOptions = {
|
|
81478
81699
|
sessionFileName,
|
|
@@ -81480,13 +81701,13 @@ async function reportAction(_opts, cmd) {
|
|
|
81480
81701
|
includeToolDetail: true,
|
|
81481
81702
|
theme
|
|
81482
81703
|
};
|
|
81483
|
-
const html = (0,
|
|
81704
|
+
const html = (0, import_sidekick_shared23.generateHtmlReport)(metrics, transcript, reportOptions);
|
|
81484
81705
|
const outFile = outputPath || path6.join(os4.tmpdir(), `sidekick-report-${Date.now()}.html`);
|
|
81485
81706
|
fs8.writeFileSync(outFile, html, "utf-8");
|
|
81486
81707
|
process.stderr.write(`Report written to: ${outFile}
|
|
81487
81708
|
`);
|
|
81488
81709
|
if (!noOpen) {
|
|
81489
|
-
(0,
|
|
81710
|
+
(0, import_sidekick_shared23.openInBrowser)(outFile);
|
|
81490
81711
|
}
|
|
81491
81712
|
} finally {
|
|
81492
81713
|
try {
|
|
@@ -81495,11 +81716,11 @@ async function reportAction(_opts, cmd) {
|
|
|
81495
81716
|
}
|
|
81496
81717
|
}
|
|
81497
81718
|
}
|
|
81498
|
-
var
|
|
81719
|
+
var import_sidekick_shared23;
|
|
81499
81720
|
var init_report = __esm({
|
|
81500
81721
|
"src/commands/report.ts"() {
|
|
81501
81722
|
"use strict";
|
|
81502
|
-
|
|
81723
|
+
import_sidekick_shared23 = __toESM(require_dist(), 1);
|
|
81503
81724
|
init_cli();
|
|
81504
81725
|
}
|
|
81505
81726
|
});
|
|
@@ -81549,7 +81770,7 @@ async function searchAction(_opts, cmd) {
|
|
|
81549
81770
|
const { encodeWorkspacePath } = await Promise.resolve().then(() => __toESM(require_dist(), 1));
|
|
81550
81771
|
projectSlug = encodeWorkspacePath(resolved);
|
|
81551
81772
|
}
|
|
81552
|
-
const results = await (0,
|
|
81773
|
+
const results = await (0, import_sidekick_shared24.searchSessions)(provider, query.trim(), {
|
|
81553
81774
|
projectSlug,
|
|
81554
81775
|
maxResults: limit
|
|
81555
81776
|
});
|
|
@@ -81585,12 +81806,12 @@ async function searchAction(_opts, cmd) {
|
|
|
81585
81806
|
}
|
|
81586
81807
|
}
|
|
81587
81808
|
}
|
|
81588
|
-
var
|
|
81809
|
+
var import_sidekick_shared24;
|
|
81589
81810
|
var init_search = __esm({
|
|
81590
81811
|
"src/commands/search.ts"() {
|
|
81591
81812
|
"use strict";
|
|
81592
81813
|
init_source();
|
|
81593
|
-
|
|
81814
|
+
import_sidekick_shared24 = __toESM(require_dist(), 1);
|
|
81594
81815
|
init_cli();
|
|
81595
81816
|
}
|
|
81596
81817
|
});
|
|
@@ -81649,12 +81870,12 @@ async function tasksAction(_opts, cmd) {
|
|
|
81649
81870
|
const jsonOutput = !!globalOpts.json;
|
|
81650
81871
|
const statusFilter = opts.status || "all";
|
|
81651
81872
|
try {
|
|
81652
|
-
const rawSlug = (0,
|
|
81653
|
-
const resolvedSlug = (0,
|
|
81873
|
+
const rawSlug = (0, import_sidekick_shared25.getProjectSlugRaw)(workspacePath);
|
|
81874
|
+
const resolvedSlug = (0, import_sidekick_shared25.getProjectSlug)(workspacePath);
|
|
81654
81875
|
const slugs = rawSlug !== resolvedSlug ? [rawSlug, resolvedSlug] : [rawSlug];
|
|
81655
81876
|
let tasks = [];
|
|
81656
81877
|
for (const slug of slugs) {
|
|
81657
|
-
tasks = await (0,
|
|
81878
|
+
tasks = await (0, import_sidekick_shared25.readTasks)(slug, { status: statusFilter });
|
|
81658
81879
|
if (tasks.length > 0) break;
|
|
81659
81880
|
}
|
|
81660
81881
|
if (jsonOutput) {
|
|
@@ -81669,12 +81890,12 @@ async function tasksAction(_opts, cmd) {
|
|
|
81669
81890
|
process.exit(1);
|
|
81670
81891
|
}
|
|
81671
81892
|
}
|
|
81672
|
-
var
|
|
81893
|
+
var import_sidekick_shared25, STATUS_COLORS, STATUS_ICONS2;
|
|
81673
81894
|
var init_tasks = __esm({
|
|
81674
81895
|
"src/commands/tasks.ts"() {
|
|
81675
81896
|
"use strict";
|
|
81676
81897
|
init_source();
|
|
81677
|
-
|
|
81898
|
+
import_sidekick_shared25 = __toESM(require_dist(), 1);
|
|
81678
81899
|
STATUS_COLORS = {
|
|
81679
81900
|
pending: source_default.yellow,
|
|
81680
81901
|
in_progress: source_default.blue,
|
|
@@ -81740,12 +81961,12 @@ async function decisionsAction(_opts, cmd) {
|
|
|
81740
81961
|
const search = opts.search;
|
|
81741
81962
|
const limit = opts.limit ? parseInt(opts.limit, 10) : void 0;
|
|
81742
81963
|
try {
|
|
81743
|
-
const rawSlug = (0,
|
|
81744
|
-
const resolvedSlug = (0,
|
|
81964
|
+
const rawSlug = (0, import_sidekick_shared26.getProjectSlugRaw)(workspacePath);
|
|
81965
|
+
const resolvedSlug = (0, import_sidekick_shared26.getProjectSlug)(workspacePath);
|
|
81745
81966
|
const slugs = rawSlug !== resolvedSlug ? [rawSlug, resolvedSlug] : [rawSlug];
|
|
81746
81967
|
let decisions = [];
|
|
81747
81968
|
for (const slug of slugs) {
|
|
81748
|
-
decisions = await (0,
|
|
81969
|
+
decisions = await (0, import_sidekick_shared26.readDecisions)(slug, { search, limit });
|
|
81749
81970
|
if (decisions.length > 0) break;
|
|
81750
81971
|
}
|
|
81751
81972
|
if (jsonOutput) {
|
|
@@ -81760,12 +81981,12 @@ async function decisionsAction(_opts, cmd) {
|
|
|
81760
81981
|
process.exit(1);
|
|
81761
81982
|
}
|
|
81762
81983
|
}
|
|
81763
|
-
var
|
|
81984
|
+
var import_sidekick_shared26, SOURCE_LABELS;
|
|
81764
81985
|
var init_decisions = __esm({
|
|
81765
81986
|
"src/commands/decisions.ts"() {
|
|
81766
81987
|
"use strict";
|
|
81767
81988
|
init_source();
|
|
81768
|
-
|
|
81989
|
+
import_sidekick_shared26 = __toESM(require_dist(), 1);
|
|
81769
81990
|
SOURCE_LABELS = {
|
|
81770
81991
|
recovery_pattern: "recovery",
|
|
81771
81992
|
plan_mode: "plan",
|
|
@@ -81827,12 +82048,12 @@ async function notesAction(_opts, cmd) {
|
|
|
81827
82048
|
const type = opts.type;
|
|
81828
82049
|
const status = opts.status;
|
|
81829
82050
|
try {
|
|
81830
|
-
const rawSlug = (0,
|
|
81831
|
-
const resolvedSlug = (0,
|
|
82051
|
+
const rawSlug = (0, import_sidekick_shared27.getProjectSlugRaw)(workspacePath);
|
|
82052
|
+
const resolvedSlug = (0, import_sidekick_shared27.getProjectSlug)(workspacePath);
|
|
81832
82053
|
const slugs = rawSlug !== resolvedSlug ? [rawSlug, resolvedSlug] : [rawSlug];
|
|
81833
82054
|
let notes = [];
|
|
81834
82055
|
for (const slug of slugs) {
|
|
81835
|
-
notes = await (0,
|
|
82056
|
+
notes = await (0, import_sidekick_shared27.readNotes)(slug, { file, type, status });
|
|
81836
82057
|
if (notes.length > 0) break;
|
|
81837
82058
|
}
|
|
81838
82059
|
if (jsonOutput) {
|
|
@@ -81847,12 +82068,12 @@ async function notesAction(_opts, cmd) {
|
|
|
81847
82068
|
process.exit(1);
|
|
81848
82069
|
}
|
|
81849
82070
|
}
|
|
81850
|
-
var
|
|
82071
|
+
var import_sidekick_shared27, TYPE_COLORS, IMPORTANCE_COLORS;
|
|
81851
82072
|
var init_notes = __esm({
|
|
81852
82073
|
"src/commands/notes.ts"() {
|
|
81853
82074
|
"use strict";
|
|
81854
82075
|
init_source();
|
|
81855
|
-
|
|
82076
|
+
import_sidekick_shared27 = __toESM(require_dist(), 1);
|
|
81856
82077
|
TYPE_COLORS = {
|
|
81857
82078
|
gotcha: source_default.red,
|
|
81858
82079
|
pattern: source_default.blue,
|
|
@@ -81897,7 +82118,7 @@ function printStatsSummary(history) {
|
|
|
81897
82118
|
`);
|
|
81898
82119
|
process.stdout.write(` ${source_default.dim(" Cache read:")} ${formatNumber(at.tokens.cacheReadTokens)}
|
|
81899
82120
|
`);
|
|
81900
|
-
process.stdout.write(` ${source_default.dim("Total cost:")} ${source_default.green((0,
|
|
82121
|
+
process.stdout.write(` ${source_default.dim("Total cost:")} ${source_default.green((0, import_sidekick_shared28.formatCost)(at.totalCost))}
|
|
81901
82122
|
`);
|
|
81902
82123
|
process.stdout.write(` ${source_default.dim("Period:")} ${at.firstDate} \u2014 ${at.lastDate}
|
|
81903
82124
|
`);
|
|
@@ -81913,7 +82134,7 @@ function printStatsSummary(history) {
|
|
|
81913
82134
|
costStr = source_default.yellow(" (\u2014)");
|
|
81914
82135
|
unpricedModels.push(m.model);
|
|
81915
82136
|
} else if (m.cost > 0) {
|
|
81916
|
-
costStr = source_default.dim(` (${(0,
|
|
82137
|
+
costStr = source_default.dim(` (${(0, import_sidekick_shared28.formatCost)(m.cost)})`);
|
|
81917
82138
|
}
|
|
81918
82139
|
process.stdout.write(` ${source_default.cyan(m.model.padEnd(30))} ${formatNumber(m.calls).padStart(8)} calls${costStr}
|
|
81919
82140
|
`);
|
|
@@ -81948,7 +82169,7 @@ function printStatsSummary(history) {
|
|
|
81948
82169
|
for (const day of recent) {
|
|
81949
82170
|
const tokens = day.tokens.inputTokens + day.tokens.outputTokens;
|
|
81950
82171
|
process.stdout.write(
|
|
81951
|
-
` ${day.date.padEnd(14)}${String(day.sessionCount).padStart(10)}${String(day.messageCount).padStart(10)}${formatNumber(tokens).padStart(12)}${(0,
|
|
82172
|
+
` ${day.date.padEnd(14)}${String(day.sessionCount).padStart(10)}${String(day.messageCount).padStart(10)}${formatNumber(tokens).padStart(12)}${(0, import_sidekick_shared28.formatCost)(day.totalCost).padStart(10)}
|
|
81952
82173
|
`
|
|
81953
82174
|
);
|
|
81954
82175
|
}
|
|
@@ -81959,7 +82180,7 @@ async function statsAction(_opts, cmd) {
|
|
|
81959
82180
|
const globalOpts = cmd.parent.opts();
|
|
81960
82181
|
const jsonOutput = !!globalOpts.json;
|
|
81961
82182
|
try {
|
|
81962
|
-
const history = await (0,
|
|
82183
|
+
const history = await (0, import_sidekick_shared28.readHistory)();
|
|
81963
82184
|
if (!history) {
|
|
81964
82185
|
if (jsonOutput) {
|
|
81965
82186
|
process.stdout.write(JSON.stringify(null) + "\n");
|
|
@@ -81981,12 +82202,12 @@ async function statsAction(_opts, cmd) {
|
|
|
81981
82202
|
process.exit(1);
|
|
81982
82203
|
}
|
|
81983
82204
|
}
|
|
81984
|
-
var
|
|
82205
|
+
var import_sidekick_shared28;
|
|
81985
82206
|
var init_stats = __esm({
|
|
81986
82207
|
"src/commands/stats.ts"() {
|
|
81987
82208
|
"use strict";
|
|
81988
82209
|
init_source();
|
|
81989
|
-
|
|
82210
|
+
import_sidekick_shared28 = __toESM(require_dist(), 1);
|
|
81990
82211
|
}
|
|
81991
82212
|
});
|
|
81992
82213
|
|
|
@@ -82105,14 +82326,14 @@ async function claudeQuotaAction(jsonOutput) {
|
|
|
82105
82326
|
const service = new QuotaService();
|
|
82106
82327
|
const [quota, peak] = await Promise.all([
|
|
82107
82328
|
service.fetchOnce(),
|
|
82108
|
-
(0,
|
|
82329
|
+
(0, import_sidekick_shared29.fetchPeakHoursStatus)()
|
|
82109
82330
|
]);
|
|
82110
82331
|
if (!quota.available) {
|
|
82111
82332
|
if (jsonOutput) {
|
|
82112
82333
|
process.stdout.write(JSON.stringify({ ...quota, peak }, null, 2) + "\n");
|
|
82113
82334
|
return;
|
|
82114
82335
|
}
|
|
82115
|
-
const descriptor = (0,
|
|
82336
|
+
const descriptor = (0, import_sidekick_shared29.describeQuotaFailure)(quota);
|
|
82116
82337
|
let msg;
|
|
82117
82338
|
let color = source_default.red;
|
|
82118
82339
|
if (descriptor) {
|
|
@@ -82147,7 +82368,7 @@ async function claudeQuotaAction(jsonOutput) {
|
|
|
82147
82368
|
const sevenReset = formatTimeUntil(quota.sevenDay.resetsAt);
|
|
82148
82369
|
const fiveProj = quota.projectedFiveHour != null ? ` ${source_default.dim("\u2192")} ${getUtilizationColor2(quota.projectedFiveHour)(String(Math.round(quota.projectedFiveHour)).padStart(3) + "%")}` : "";
|
|
82149
82370
|
const sevenProj = quota.projectedSevenDay != null ? ` ${source_default.dim("\u2192")} ${getUtilizationColor2(quota.projectedSevenDay)(String(Math.round(quota.projectedSevenDay)).padStart(3) + "%")}` : "";
|
|
82150
|
-
const active = (0,
|
|
82371
|
+
const active = (0, import_sidekick_shared29.getActiveAccount)();
|
|
82151
82372
|
if (active) {
|
|
82152
82373
|
process.stdout.write(source_default.dim(`Account: ${active.email}${active.label ? ` (${active.label})` : ""}
|
|
82153
82374
|
`));
|
|
@@ -82168,13 +82389,13 @@ function printPeakHoursSummary(peak) {
|
|
|
82168
82389
|
}
|
|
82169
82390
|
async function codexQuotaAction(provider, globalOpts, jsonOutput) {
|
|
82170
82391
|
const workspacePath = globalOpts.project || process.cwd();
|
|
82171
|
-
const activeAccount = (0,
|
|
82172
|
-
let quota = activeAccount ? (0,
|
|
82392
|
+
const activeAccount = (0, import_sidekick_shared29.getActiveCodexAccount)();
|
|
82393
|
+
let quota = activeAccount ? (0, import_sidekick_shared29.readQuotaSnapshot)("codex", activeAccount.id) : null;
|
|
82173
82394
|
const sessions = provider.findAllSessions(workspacePath);
|
|
82174
82395
|
if (sessions.length > 0) {
|
|
82175
82396
|
const captured = { rl: void 0 };
|
|
82176
82397
|
try {
|
|
82177
|
-
const result = (0,
|
|
82398
|
+
const result = (0, import_sidekick_shared29.createWatcher)({
|
|
82178
82399
|
provider,
|
|
82179
82400
|
workspacePath,
|
|
82180
82401
|
callbacks: {
|
|
@@ -82191,7 +82412,7 @@ async function codexQuotaAction(provider, globalOpts, jsonOutput) {
|
|
|
82191
82412
|
result.watcher.stop();
|
|
82192
82413
|
} catch {
|
|
82193
82414
|
}
|
|
82194
|
-
const liveQuota = captured.rl ? (0,
|
|
82415
|
+
const liveQuota = captured.rl ? (0, import_sidekick_shared29.quotaFromCodexRateLimits)({
|
|
82195
82416
|
primary: captured.rl.primary ? {
|
|
82196
82417
|
used_percent: captured.rl.primary.usedPercent,
|
|
82197
82418
|
window_minutes: captured.rl.primary.windowMinutes,
|
|
@@ -82206,7 +82427,7 @@ async function codexQuotaAction(provider, globalOpts, jsonOutput) {
|
|
|
82206
82427
|
if (liveQuota) {
|
|
82207
82428
|
quota = liveQuota;
|
|
82208
82429
|
if (activeAccount) {
|
|
82209
|
-
(0,
|
|
82430
|
+
(0, import_sidekick_shared29.writeQuotaSnapshot)("codex", activeAccount.id, liveQuota);
|
|
82210
82431
|
}
|
|
82211
82432
|
}
|
|
82212
82433
|
}
|
|
@@ -82250,12 +82471,12 @@ async function codexQuotaAction(provider, globalOpts, jsonOutput) {
|
|
|
82250
82471
|
`);
|
|
82251
82472
|
}
|
|
82252
82473
|
}
|
|
82253
|
-
var
|
|
82474
|
+
var import_sidekick_shared29;
|
|
82254
82475
|
var init_quota = __esm({
|
|
82255
82476
|
"src/commands/quota.ts"() {
|
|
82256
82477
|
"use strict";
|
|
82257
82478
|
init_source();
|
|
82258
|
-
|
|
82479
|
+
import_sidekick_shared29 = __toESM(require_dist(), 1);
|
|
82259
82480
|
init_cli();
|
|
82260
82481
|
init_QuotaService();
|
|
82261
82482
|
init_peakHoursRender();
|
|
@@ -82308,9 +82529,9 @@ async function statusAction(_opts, cmd) {
|
|
|
82308
82529
|
const providerId = resolveProviderId(globalOpts);
|
|
82309
82530
|
const wantsPeak = providerId === "claude-code";
|
|
82310
82531
|
const [claude, openai, peak] = await Promise.all([
|
|
82311
|
-
(0,
|
|
82312
|
-
(0,
|
|
82313
|
-
wantsPeak ? (0,
|
|
82532
|
+
(0, import_sidekick_shared30.fetchProviderStatus)(),
|
|
82533
|
+
(0, import_sidekick_shared30.fetchOpenAIStatus)(),
|
|
82534
|
+
wantsPeak ? (0, import_sidekick_shared30.fetchPeakHoursStatus)() : Promise.resolve(null)
|
|
82314
82535
|
]);
|
|
82315
82536
|
if (jsonOutput) {
|
|
82316
82537
|
process.stdout.write(JSON.stringify({ claude, openai, peak }, null, 2) + "\n");
|
|
@@ -82324,12 +82545,12 @@ async function statusAction(_opts, cmd) {
|
|
|
82324
82545
|
printPeakHoursBlock(peak);
|
|
82325
82546
|
}
|
|
82326
82547
|
}
|
|
82327
|
-
var
|
|
82548
|
+
var import_sidekick_shared30;
|
|
82328
82549
|
var init_status = __esm({
|
|
82329
82550
|
"src/commands/status.ts"() {
|
|
82330
82551
|
"use strict";
|
|
82331
82552
|
init_source();
|
|
82332
|
-
|
|
82553
|
+
import_sidekick_shared30 = __toESM(require_dist(), 1);
|
|
82333
82554
|
init_peakHoursRender();
|
|
82334
82555
|
init_cli();
|
|
82335
82556
|
}
|
|
@@ -82343,18 +82564,18 @@ __export(peak_exports, {
|
|
|
82343
82564
|
async function peakAction(_opts, cmd) {
|
|
82344
82565
|
const globalOpts = cmd.parent.opts();
|
|
82345
82566
|
const jsonOutput = !!globalOpts.json;
|
|
82346
|
-
const state = await (0,
|
|
82567
|
+
const state = await (0, import_sidekick_shared31.fetchPeakHoursStatus)();
|
|
82347
82568
|
if (jsonOutput) {
|
|
82348
82569
|
process.stdout.write(JSON.stringify(state, null, 2) + "\n");
|
|
82349
82570
|
return;
|
|
82350
82571
|
}
|
|
82351
82572
|
printPeakHoursBlock(state);
|
|
82352
82573
|
}
|
|
82353
|
-
var
|
|
82574
|
+
var import_sidekick_shared31;
|
|
82354
82575
|
var init_peak = __esm({
|
|
82355
82576
|
"src/commands/peak.ts"() {
|
|
82356
82577
|
"use strict";
|
|
82357
|
-
|
|
82578
|
+
import_sidekick_shared31 = __toESM(require_dist(), 1);
|
|
82358
82579
|
init_peakHoursRender();
|
|
82359
82580
|
}
|
|
82360
82581
|
});
|
|
@@ -82386,13 +82607,13 @@ async function accountAction(_opts, cmd) {
|
|
|
82386
82607
|
}
|
|
82387
82608
|
function claudeAccountAction(opts, jsonOutput) {
|
|
82388
82609
|
if (opts.add) {
|
|
82389
|
-
const result = (0,
|
|
82610
|
+
const result = (0, import_sidekick_shared32.addCurrentAccount)(opts.label);
|
|
82390
82611
|
if (!result.success) {
|
|
82391
82612
|
process.stderr.write(source_default.red(result.error ?? "Failed to save account.") + "\n");
|
|
82392
82613
|
process.exit(1);
|
|
82393
82614
|
return;
|
|
82394
82615
|
}
|
|
82395
|
-
const active2 = (0,
|
|
82616
|
+
const active2 = (0, import_sidekick_shared32.readActiveClaudeAccount)();
|
|
82396
82617
|
if (jsonOutput) {
|
|
82397
82618
|
process.stdout.write(JSON.stringify({ action: "added", provider: "claude-code", email: active2?.email, label: opts.label }) + "\n");
|
|
82398
82619
|
} else {
|
|
@@ -82401,14 +82622,14 @@ function claudeAccountAction(opts, jsonOutput) {
|
|
|
82401
82622
|
return;
|
|
82402
82623
|
}
|
|
82403
82624
|
if (opts.remove) {
|
|
82404
|
-
const accounts2 = (0,
|
|
82625
|
+
const accounts2 = (0, import_sidekick_shared32.listAccounts)();
|
|
82405
82626
|
const target = findClaudeAccount(opts.remove, accounts2);
|
|
82406
82627
|
if (!target) {
|
|
82407
82628
|
process.stderr.write(source_default.red(`Account "${opts.remove}" not found.`) + "\n");
|
|
82408
82629
|
process.exit(1);
|
|
82409
82630
|
return;
|
|
82410
82631
|
}
|
|
82411
|
-
const result = (0,
|
|
82632
|
+
const result = (0, import_sidekick_shared32.removeAccount)(target.uuid);
|
|
82412
82633
|
if (!result.success) {
|
|
82413
82634
|
process.stderr.write(source_default.red(result.error ?? "Failed to remove account.") + "\n");
|
|
82414
82635
|
process.exit(1);
|
|
@@ -82422,14 +82643,14 @@ function claudeAccountAction(opts, jsonOutput) {
|
|
|
82422
82643
|
return;
|
|
82423
82644
|
}
|
|
82424
82645
|
if (opts.switchTo) {
|
|
82425
|
-
const accounts2 = (0,
|
|
82646
|
+
const accounts2 = (0, import_sidekick_shared32.listAccounts)();
|
|
82426
82647
|
const target = findClaudeAccount(opts.switchTo, accounts2);
|
|
82427
82648
|
if (!target) {
|
|
82428
82649
|
process.stderr.write(source_default.red(`Account "${opts.switchTo}" not found.`) + "\n");
|
|
82429
82650
|
process.exit(1);
|
|
82430
82651
|
return;
|
|
82431
82652
|
}
|
|
82432
|
-
const result = (0,
|
|
82653
|
+
const result = (0, import_sidekick_shared32.switchToAccount)(target.uuid);
|
|
82433
82654
|
if (!result.success) {
|
|
82434
82655
|
process.stderr.write(source_default.red(result.error ?? "Failed to switch.") + "\n");
|
|
82435
82656
|
process.exit(1);
|
|
@@ -82443,17 +82664,17 @@ function claudeAccountAction(opts, jsonOutput) {
|
|
|
82443
82664
|
return;
|
|
82444
82665
|
}
|
|
82445
82666
|
if (opts.switch) {
|
|
82446
|
-
const accounts2 = (0,
|
|
82667
|
+
const accounts2 = (0, import_sidekick_shared32.listAccounts)();
|
|
82447
82668
|
if (accounts2.length < 2) {
|
|
82448
82669
|
process.stderr.write(source_default.yellow("Need at least 2 saved accounts to switch.") + "\n");
|
|
82449
82670
|
process.exit(1);
|
|
82450
82671
|
return;
|
|
82451
82672
|
}
|
|
82452
|
-
const active2 = (0,
|
|
82673
|
+
const active2 = (0, import_sidekick_shared32.getActiveAccount)();
|
|
82453
82674
|
const currentIdx = active2 ? accounts2.findIndex((a) => a.uuid === active2.uuid) : -1;
|
|
82454
82675
|
const nextIdx = (currentIdx + 1) % accounts2.length;
|
|
82455
82676
|
const target = accounts2[nextIdx];
|
|
82456
|
-
const result = (0,
|
|
82677
|
+
const result = (0, import_sidekick_shared32.switchToAccount)(target.uuid);
|
|
82457
82678
|
if (!result.success) {
|
|
82458
82679
|
process.stderr.write(source_default.red(result.error ?? "Failed to switch.") + "\n");
|
|
82459
82680
|
process.exit(1);
|
|
@@ -82466,9 +82687,9 @@ function claudeAccountAction(opts, jsonOutput) {
|
|
|
82466
82687
|
}
|
|
82467
82688
|
return;
|
|
82468
82689
|
}
|
|
82469
|
-
const accounts = (0,
|
|
82690
|
+
const accounts = (0, import_sidekick_shared32.listAccounts)();
|
|
82470
82691
|
if (accounts.length === 0) {
|
|
82471
|
-
const current = (0,
|
|
82692
|
+
const current = (0, import_sidekick_shared32.readActiveClaudeAccount)();
|
|
82472
82693
|
if (jsonOutput) {
|
|
82473
82694
|
process.stdout.write(JSON.stringify({ provider: "claude-code", accounts: [], current: current ?? null }) + "\n");
|
|
82474
82695
|
} else if (current) {
|
|
@@ -82480,14 +82701,14 @@ function claudeAccountAction(opts, jsonOutput) {
|
|
|
82480
82701
|
return;
|
|
82481
82702
|
}
|
|
82482
82703
|
if (jsonOutput) {
|
|
82483
|
-
const active2 = (0,
|
|
82704
|
+
const active2 = (0, import_sidekick_shared32.getActiveAccount)();
|
|
82484
82705
|
process.stdout.write(JSON.stringify({
|
|
82485
82706
|
provider: "claude-code",
|
|
82486
82707
|
accounts: accounts.map((a) => ({ ...a, active: a.uuid === active2?.uuid }))
|
|
82487
82708
|
}, null, 2) + "\n");
|
|
82488
82709
|
return;
|
|
82489
82710
|
}
|
|
82490
|
-
const active = (0,
|
|
82711
|
+
const active = (0, import_sidekick_shared32.getActiveAccount)();
|
|
82491
82712
|
process.stdout.write(source_default.bold("Claude Accounts\n"));
|
|
82492
82713
|
process.stdout.write(source_default.dim("\u2500".repeat(50) + "\n"));
|
|
82493
82714
|
for (const account of accounts) {
|
|
@@ -82534,7 +82755,7 @@ function codexAccountAction(opts, jsonOutput) {
|
|
|
82534
82755
|
process.exit(1);
|
|
82535
82756
|
return;
|
|
82536
82757
|
}
|
|
82537
|
-
const prepared = (0,
|
|
82758
|
+
const prepared = (0, import_sidekick_shared32.prepareCodexAccount)(opts.label);
|
|
82538
82759
|
if (!prepared.success) {
|
|
82539
82760
|
process.stderr.write(source_default.red(prepared.error ?? "Failed to prepare Codex account.") + "\n");
|
|
82540
82761
|
process.exit(1);
|
|
@@ -82552,14 +82773,14 @@ function codexAccountAction(opts, jsonOutput) {
|
|
|
82552
82773
|
process.exit(1);
|
|
82553
82774
|
return;
|
|
82554
82775
|
}
|
|
82555
|
-
const finalized = (0,
|
|
82776
|
+
const finalized = (0, import_sidekick_shared32.finalizeCodexAccount)(prepared.profileId);
|
|
82556
82777
|
if (!finalized.success) {
|
|
82557
82778
|
process.stderr.write(source_default.red(finalized.error ?? "Failed to finalize Codex account.") + "\n");
|
|
82558
82779
|
process.exit(1);
|
|
82559
82780
|
return;
|
|
82560
82781
|
}
|
|
82561
82782
|
}
|
|
82562
|
-
const active2 = (0,
|
|
82783
|
+
const active2 = (0, import_sidekick_shared32.getActiveCodexAccount)();
|
|
82563
82784
|
if (jsonOutput) {
|
|
82564
82785
|
process.stdout.write(JSON.stringify({
|
|
82565
82786
|
action: "added",
|
|
@@ -82575,14 +82796,14 @@ function codexAccountAction(opts, jsonOutput) {
|
|
|
82575
82796
|
return;
|
|
82576
82797
|
}
|
|
82577
82798
|
if (opts.remove) {
|
|
82578
|
-
const accounts2 = (0,
|
|
82799
|
+
const accounts2 = (0, import_sidekick_shared32.listCodexAccounts)();
|
|
82579
82800
|
const target = findCodexAccount(opts.remove, accounts2);
|
|
82580
82801
|
if (!target) {
|
|
82581
82802
|
process.stderr.write(source_default.red(`Codex account "${opts.remove}" not found.`) + "\n");
|
|
82582
82803
|
process.exit(1);
|
|
82583
82804
|
return;
|
|
82584
82805
|
}
|
|
82585
|
-
const result = (0,
|
|
82806
|
+
const result = (0, import_sidekick_shared32.removeCodexAccount)(target.id);
|
|
82586
82807
|
if (!result.success) {
|
|
82587
82808
|
process.stderr.write(source_default.red(result.error ?? "Failed to remove Codex account.") + "\n");
|
|
82588
82809
|
process.exit(1);
|
|
@@ -82596,14 +82817,14 @@ function codexAccountAction(opts, jsonOutput) {
|
|
|
82596
82817
|
return;
|
|
82597
82818
|
}
|
|
82598
82819
|
if (opts.switchTo) {
|
|
82599
|
-
const accounts2 = (0,
|
|
82820
|
+
const accounts2 = (0, import_sidekick_shared32.listCodexAccounts)();
|
|
82600
82821
|
const target = findCodexAccount(opts.switchTo, accounts2);
|
|
82601
82822
|
if (!target) {
|
|
82602
82823
|
process.stderr.write(source_default.red(`Codex account "${opts.switchTo}" not found.`) + "\n");
|
|
82603
82824
|
process.exit(1);
|
|
82604
82825
|
return;
|
|
82605
82826
|
}
|
|
82606
|
-
const result = (0,
|
|
82827
|
+
const result = (0, import_sidekick_shared32.switchToCodexAccount)(target.id);
|
|
82607
82828
|
if (!result.success) {
|
|
82608
82829
|
process.stderr.write(source_default.red(result.error ?? "Failed to switch Codex account.") + "\n");
|
|
82609
82830
|
process.exit(1);
|
|
@@ -82617,17 +82838,17 @@ function codexAccountAction(opts, jsonOutput) {
|
|
|
82617
82838
|
return;
|
|
82618
82839
|
}
|
|
82619
82840
|
if (opts.switch) {
|
|
82620
|
-
const accounts2 = (0,
|
|
82841
|
+
const accounts2 = (0, import_sidekick_shared32.listCodexAccounts)();
|
|
82621
82842
|
if (accounts2.length < 2) {
|
|
82622
82843
|
process.stderr.write(source_default.yellow("Need at least 2 saved Codex accounts to switch.") + "\n");
|
|
82623
82844
|
process.exit(1);
|
|
82624
82845
|
return;
|
|
82625
82846
|
}
|
|
82626
|
-
const active2 = (0,
|
|
82847
|
+
const active2 = (0, import_sidekick_shared32.getActiveCodexAccount)();
|
|
82627
82848
|
const currentIdx = active2 ? accounts2.findIndex((account) => account.id === active2.id) : -1;
|
|
82628
82849
|
const nextIdx = (currentIdx + 1) % accounts2.length;
|
|
82629
82850
|
const target = accounts2[nextIdx];
|
|
82630
|
-
const result = (0,
|
|
82851
|
+
const result = (0, import_sidekick_shared32.switchToCodexAccount)(target.id);
|
|
82631
82852
|
if (!result.success) {
|
|
82632
82853
|
process.stderr.write(source_default.red(result.error ?? "Failed to switch Codex account.") + "\n");
|
|
82633
82854
|
process.exit(1);
|
|
@@ -82640,7 +82861,7 @@ function codexAccountAction(opts, jsonOutput) {
|
|
|
82640
82861
|
}
|
|
82641
82862
|
return;
|
|
82642
82863
|
}
|
|
82643
|
-
const accounts = (0,
|
|
82864
|
+
const accounts = (0, import_sidekick_shared32.listCodexAccounts)();
|
|
82644
82865
|
if (accounts.length === 0) {
|
|
82645
82866
|
if (jsonOutput) {
|
|
82646
82867
|
process.stdout.write(JSON.stringify({ provider: "codex", accounts: [], current: null }) + "\n");
|
|
@@ -82650,7 +82871,7 @@ function codexAccountAction(opts, jsonOutput) {
|
|
|
82650
82871
|
return;
|
|
82651
82872
|
}
|
|
82652
82873
|
if (jsonOutput) {
|
|
82653
|
-
const active2 = (0,
|
|
82874
|
+
const active2 = (0, import_sidekick_shared32.getActiveCodexAccount)();
|
|
82654
82875
|
process.stdout.write(JSON.stringify({
|
|
82655
82876
|
provider: "codex",
|
|
82656
82877
|
accounts: accounts.map((account) => ({
|
|
@@ -82660,7 +82881,7 @@ function codexAccountAction(opts, jsonOutput) {
|
|
|
82660
82881
|
}, null, 2) + "\n");
|
|
82661
82882
|
return;
|
|
82662
82883
|
}
|
|
82663
|
-
const active = (0,
|
|
82884
|
+
const active = (0, import_sidekick_shared32.getActiveCodexAccount)();
|
|
82664
82885
|
process.stdout.write(source_default.bold("Codex Accounts\n"));
|
|
82665
82886
|
process.stdout.write(source_default.dim("\u2500".repeat(50) + "\n"));
|
|
82666
82887
|
for (const account of accounts) {
|
|
@@ -82671,12 +82892,12 @@ function codexAccountAction(opts, jsonOutput) {
|
|
|
82671
82892
|
`);
|
|
82672
82893
|
}
|
|
82673
82894
|
}
|
|
82674
|
-
var
|
|
82895
|
+
var import_sidekick_shared32;
|
|
82675
82896
|
var init_account = __esm({
|
|
82676
82897
|
"src/commands/account.ts"() {
|
|
82677
82898
|
"use strict";
|
|
82678
82899
|
init_source();
|
|
82679
|
-
|
|
82900
|
+
import_sidekick_shared32 = __toESM(require_dist(), 1);
|
|
82680
82901
|
init_cli();
|
|
82681
82902
|
}
|
|
82682
82903
|
});
|
|
@@ -82691,12 +82912,12 @@ async function handoffAction(_opts, cmd) {
|
|
|
82691
82912
|
const workspacePath = globalOpts.project || process.cwd();
|
|
82692
82913
|
const jsonOutput = !!globalOpts.json;
|
|
82693
82914
|
try {
|
|
82694
|
-
const rawSlug = (0,
|
|
82695
|
-
const resolvedSlug = (0,
|
|
82915
|
+
const rawSlug = (0, import_sidekick_shared33.getProjectSlugRaw)(workspacePath);
|
|
82916
|
+
const resolvedSlug = (0, import_sidekick_shared33.getProjectSlug)(workspacePath);
|
|
82696
82917
|
const slugs = rawSlug !== resolvedSlug ? [rawSlug, resolvedSlug] : [rawSlug];
|
|
82697
82918
|
let content = null;
|
|
82698
82919
|
for (const slug of slugs) {
|
|
82699
|
-
content = await (0,
|
|
82920
|
+
content = await (0, import_sidekick_shared33.readLatestHandoff)(slug);
|
|
82700
82921
|
if (content) break;
|
|
82701
82922
|
}
|
|
82702
82923
|
if (!content) {
|
|
@@ -82721,12 +82942,12 @@ async function handoffAction(_opts, cmd) {
|
|
|
82721
82942
|
process.exit(1);
|
|
82722
82943
|
}
|
|
82723
82944
|
}
|
|
82724
|
-
var
|
|
82945
|
+
var import_sidekick_shared33;
|
|
82725
82946
|
var init_handoff = __esm({
|
|
82726
82947
|
"src/commands/handoff.ts"() {
|
|
82727
82948
|
"use strict";
|
|
82728
82949
|
init_source();
|
|
82729
|
-
|
|
82950
|
+
import_sidekick_shared33 = __toESM(require_dist(), 1);
|
|
82730
82951
|
}
|
|
82731
82952
|
});
|
|
82732
82953
|
|
|
@@ -82740,35 +82961,35 @@ function resolveProviderId(opts, defaultProvider = "auto") {
|
|
|
82740
82961
|
if (defaultProvider !== "auto") {
|
|
82741
82962
|
return defaultProvider;
|
|
82742
82963
|
}
|
|
82743
|
-
return (0,
|
|
82964
|
+
return (0, import_sidekick_shared34.detectProvider)();
|
|
82744
82965
|
}
|
|
82745
82966
|
function resolveProvider(opts) {
|
|
82746
82967
|
const id = resolveProviderId(opts);
|
|
82747
82968
|
switch (id) {
|
|
82748
82969
|
case "opencode":
|
|
82749
|
-
return new
|
|
82970
|
+
return new import_sidekick_shared35.OpenCodeProvider();
|
|
82750
82971
|
case "codex":
|
|
82751
|
-
return new
|
|
82972
|
+
return new import_sidekick_shared35.CodexProvider();
|
|
82752
82973
|
case "claude-code":
|
|
82753
82974
|
default:
|
|
82754
|
-
return new
|
|
82975
|
+
return new import_sidekick_shared35.ClaudeCodeProvider();
|
|
82755
82976
|
}
|
|
82756
82977
|
}
|
|
82757
|
-
var
|
|
82978
|
+
var import_sidekick_shared34, import_node, import_sidekick_shared35, defaultAccountsReady, program2, dashCmd, dumpCmd, ctxCmd, reportCmd, searchCmd, tasksCmd, decisionsCmd, notesCmd, statsCmd, quotaCmd, statusCmd, peakCmd, accountCmd, handoffCmd;
|
|
82758
82979
|
var init_cli = __esm({
|
|
82759
82980
|
"src/cli.ts"() {
|
|
82760
82981
|
init_esm();
|
|
82761
|
-
import_sidekick_shared33 = __toESM(require_dist(), 1);
|
|
82762
|
-
import_node = __toESM(require_node(), 1);
|
|
82763
82982
|
import_sidekick_shared34 = __toESM(require_dist(), 1);
|
|
82983
|
+
import_node = __toESM(require_node(), 1);
|
|
82984
|
+
import_sidekick_shared35 = __toESM(require_dist(), 1);
|
|
82764
82985
|
(0, import_node.hydratePricingCatalog)({
|
|
82765
82986
|
cacheDir: path7.join(os5.homedir(), ".config", "sidekick")
|
|
82766
82987
|
}).catch(() => {
|
|
82767
82988
|
});
|
|
82768
|
-
defaultAccountsReady = (0,
|
|
82989
|
+
defaultAccountsReady = (0, import_sidekick_shared34.ensureDefaultAccounts)().catch(() => {
|
|
82769
82990
|
});
|
|
82770
82991
|
program2 = new Command();
|
|
82771
|
-
program2.name("sidekick").description("Query Sidekick project intelligence from the command line").version("0.18.
|
|
82992
|
+
program2.name("sidekick").description("Query Sidekick project intelligence from the command line").version("0.18.1").option("--json", "Output as JSON").option("--project <path>", "Override project path (default: cwd)").option("--provider <id>", "Provider: claude-code, opencode, codex, auto (default: auto)");
|
|
82772
82993
|
program2.hook("preAction", async () => {
|
|
82773
82994
|
await defaultAccountsReady;
|
|
82774
82995
|
});
|