sidekick-agent-hub 0.12.7 → 0.12.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/sidekick-cli.mjs +422 -331
- package/package.json +1 -1
package/dist/sidekick-cli.mjs
CHANGED
|
@@ -17997,7 +17997,7 @@ var init_UpdateCheckService = __esm({
|
|
|
17997
17997
|
/** Run the update check (one-shot). */
|
|
17998
17998
|
async check() {
|
|
17999
17999
|
try {
|
|
18000
|
-
const current = "0.12.
|
|
18000
|
+
const current = "0.12.8";
|
|
18001
18001
|
const cached = this.readCache();
|
|
18002
18002
|
let latest;
|
|
18003
18003
|
if (cached && Date.now() - cached.checkedAt < CACHE_TTL_MS) {
|
|
@@ -18102,6 +18102,28 @@ function formatElapsed(startTime) {
|
|
|
18102
18102
|
const s = secs % 60;
|
|
18103
18103
|
return `${String(h).padStart(2, "0")}:${String(m).padStart(2, "0")}:${String(s).padStart(2, "0")}`;
|
|
18104
18104
|
}
|
|
18105
|
+
function sectionHeader(title, width = 40) {
|
|
18106
|
+
const prefix = "\u2500\u2500 ";
|
|
18107
|
+
const suffix = " ";
|
|
18108
|
+
const fillLen = Math.max(0, width - prefix.length - title.length - suffix.length);
|
|
18109
|
+
const fill = "\u2500".repeat(fillLen);
|
|
18110
|
+
return `{grey-fg}${prefix}{/grey-fg}{bold}${title}{/bold}{grey-fg}${suffix}${fill}{/grey-fg}`;
|
|
18111
|
+
}
|
|
18112
|
+
function makeColorBar(percent, width, color = "green") {
|
|
18113
|
+
const clamped = Math.max(0, Math.min(100, percent));
|
|
18114
|
+
const filled = Math.round(clamped / 100 * width);
|
|
18115
|
+
const empty = width - filled;
|
|
18116
|
+
return `{${color}-fg}${"\u2588".repeat(filled)}{/${color}-fg}{grey-fg}${"\u2591".repeat(empty)}{/grey-fg}`;
|
|
18117
|
+
}
|
|
18118
|
+
function makeSparkline(data, maxWidth = 25) {
|
|
18119
|
+
const trimmed = data.slice(-maxWidth);
|
|
18120
|
+
if (trimmed.length === 0) return { spark: "", max: 0, latest: 0 };
|
|
18121
|
+
const max = Math.max(...trimmed, 1);
|
|
18122
|
+
const latest = trimmed[trimmed.length - 1];
|
|
18123
|
+
const chars = [" ", "\u2581", "\u2582", "\u2583", "\u2584", "\u2585", "\u2586", "\u2587", "\u2588"];
|
|
18124
|
+
const spark = trimmed.map((v) => chars[Math.min(8, Math.round(v / max * 8))]).join("");
|
|
18125
|
+
return { spark, max, latest };
|
|
18126
|
+
}
|
|
18105
18127
|
function makeBar(percent, width) {
|
|
18106
18128
|
const clamped = Math.max(0, Math.min(100, percent));
|
|
18107
18129
|
const filled = Math.round(clamped / 100 * width);
|
|
@@ -19219,7 +19241,7 @@ function renderContextAttribution(attr) {
|
|
|
19219
19241
|
const total = categories.reduce((sum, c) => sum + c.tokens, 0);
|
|
19220
19242
|
if (total === 0) return [];
|
|
19221
19243
|
const barWidth = 30;
|
|
19222
|
-
const lines = ["
|
|
19244
|
+
const lines = [sectionHeader("Context Attribution", 40), ""];
|
|
19223
19245
|
let bar = " ";
|
|
19224
19246
|
for (const cat of categories) {
|
|
19225
19247
|
if (cat.tokens === 0) continue;
|
|
@@ -19251,6 +19273,7 @@ var init_SessionsPanel = __esm({
|
|
|
19251
19273
|
id = "sessions";
|
|
19252
19274
|
title = "Sessions";
|
|
19253
19275
|
shortcutKey = 1;
|
|
19276
|
+
emptyStateHint = "Start an agent session in another terminal.";
|
|
19254
19277
|
mindMapView = "tree";
|
|
19255
19278
|
mindMapFilter = "all";
|
|
19256
19279
|
diffCache;
|
|
@@ -19436,75 +19459,67 @@ ${hint}{/grey-fg}`;
|
|
|
19436
19459
|
const t = m.tokens;
|
|
19437
19460
|
const c = m.context;
|
|
19438
19461
|
const contextColor = getUtilizationColor(c.percent);
|
|
19439
|
-
const
|
|
19440
|
-
const filled = Math.round(c.percent / 100 * barWidth);
|
|
19441
|
-
const empty = barWidth - filled;
|
|
19442
|
-
const bar = "\u2588".repeat(filled) + "\u2591".repeat(empty);
|
|
19462
|
+
const w2 = detailWidth();
|
|
19443
19463
|
const elapsed = m.sessionStartTime ? formatElapsed(m.sessionStartTime) : "--:--:--";
|
|
19444
|
-
const burnData = m.burnRate.length > 0 ? m.burnRate : [0];
|
|
19445
|
-
const latest = burnData[burnData.length - 1];
|
|
19446
|
-
const max = Math.max(...burnData, 1);
|
|
19447
|
-
const chars = [" ", "\u2581", "\u2582", "\u2583", "\u2584", "\u2585", "\u2586", "\u2587", "\u2588"];
|
|
19448
|
-
const spark = burnData.slice(-25).map((v) => chars[Math.min(8, Math.round(v / max * 8))]).join("");
|
|
19449
|
-
const runningAgents = m.subagents.filter((a) => a.status === "running").length;
|
|
19450
|
-
const completedAgents = m.subagents.filter((a) => a.status === "completed").length;
|
|
19451
|
-
const agentSummary = m.subagents.length > 0 ? `${m.subagents.length} (${runningAgents} running, ${completedAgents} done)` : "0";
|
|
19452
19464
|
const recentEvent = [...m.timeline].reverse().find(
|
|
19453
19465
|
(e) => e.type !== "user" && e.type !== "tool_result"
|
|
19454
19466
|
);
|
|
19455
19467
|
const recentLine = recentEvent ? (() => {
|
|
19456
19468
|
const prefix = `[${formatTime(recentEvent.timestamp)}] ${recentEvent.type.padEnd(12)} `;
|
|
19457
|
-
const maxSummary = Math.max(20,
|
|
19469
|
+
const maxSummary = Math.max(20, w2 - prefix.length);
|
|
19458
19470
|
return `{yellow-fg}${prefix}${truncate(recentEvent.summary || "", maxSummary)}{/yellow-fg}`;
|
|
19459
19471
|
})() : "{grey-fg}(no events yet){/grey-fg}";
|
|
19472
|
+
const compactionSuffix = m.compactionCount > 0 ? ` {bold}${m.compactionCount}{/bold}{grey-fg} compaction${m.compactionCount !== 1 ? "s" : ""}{/grey-fg}` : "";
|
|
19460
19473
|
const lines = [
|
|
19461
|
-
|
|
19462
|
-
|
|
19463
|
-
|
|
19464
|
-
`{bold}Elapsed:{/bold} ${elapsed}`,
|
|
19465
|
-
`{bold}Provider:{/bold} ${m.providerName || "unknown"}`,
|
|
19466
|
-
`{bold}Model:{/bold} ${m.currentModel || "unknown"}`,
|
|
19467
|
-
`{bold}Events:{/bold} ${m.eventCount}`,
|
|
19468
|
-
`{bold}Compactions:{/bold} ${m.compactionCount}`,
|
|
19469
|
-
`{bold}Subagents:{/bold} ${agentSummary}`,
|
|
19470
|
-
"",
|
|
19471
|
-
"{bold}Tokens{/bold}",
|
|
19472
|
-
` Input: ${fmtNum(t.input)}`,
|
|
19473
|
-
` Output: ${fmtNum(t.output)}`,
|
|
19474
|
-
` Cache Read: ${fmtNum(t.cacheRead)}`,
|
|
19475
|
-
` Cache Write: ${fmtNum(t.cacheWrite)}`,
|
|
19476
|
-
...t.cacheRead + t.input > 0 ? [` Hit Rate: ${(t.cacheRead / (t.cacheRead + t.input) * 100).toFixed(1)}%`] : [],
|
|
19477
|
-
` Cost: {green-fg}$${t.cost.toFixed(4)}{/green-fg}`,
|
|
19478
|
-
"",
|
|
19479
|
-
"{bold}Context{/bold}",
|
|
19480
|
-
` {${contextColor}-fg}${bar}{/${contextColor}-fg}`,
|
|
19481
|
-
` {bold}${c.percent}%{/bold} ${fmtNum(c.used)} / ${fmtNum(c.limit)}`
|
|
19474
|
+
`{bold}${elapsed}{/bold}{grey-fg} elapsed{/grey-fg} {bold}${m.eventCount}{/bold}{grey-fg} events{/grey-fg}${compactionSuffix}`,
|
|
19475
|
+
`{grey-fg}Provider{/grey-fg} {bold}${m.providerName || "unknown"}{/bold} {grey-fg}Model{/grey-fg} {bold}${m.currentModel || "unknown"}{/bold}`,
|
|
19476
|
+
recentLine
|
|
19482
19477
|
];
|
|
19483
|
-
if (m.contextTimeline && m.contextTimeline.length > 1) {
|
|
19484
|
-
const ctxPoints = m.contextTimeline.slice(-25);
|
|
19485
|
-
const ctxMax = Math.max(...ctxPoints.map((p) => p.inputTokens), 1);
|
|
19486
|
-
const sparkChars = [" ", "\u2581", "\u2582", "\u2583", "\u2584", "\u2585", "\u2586", "\u2587", "\u2588"];
|
|
19487
|
-
const ctxSpark = ctxPoints.map((p) => sparkChars[Math.min(8, Math.round(p.inputTokens / ctxMax * 8))]).join("");
|
|
19488
|
-
lines.push(` {grey-fg}${ctxSpark}{/grey-fg} history`);
|
|
19489
|
-
}
|
|
19490
19478
|
if (m.permissionMode && m.permissionMode !== "default") {
|
|
19491
19479
|
const modeColors = { bypassPermissions: "red", acceptEdits: "magenta", plan: "green" };
|
|
19492
19480
|
const modeLabels = { bypassPermissions: "Bypass Permissions", acceptEdits: "Accept Edits", plan: "Plan Mode" };
|
|
19493
19481
|
const modeColor = modeColors[m.permissionMode] || "grey";
|
|
19494
19482
|
const modeLabel = modeLabels[m.permissionMode] || m.permissionMode;
|
|
19495
|
-
lines.push(
|
|
19483
|
+
lines.push(`{grey-fg}Permission{/grey-fg} {${modeColor}-fg}{bold}${modeLabel}{/bold}{/${modeColor}-fg}`);
|
|
19484
|
+
}
|
|
19485
|
+
if (m.subagents.length > 0) {
|
|
19486
|
+
const runningAgents = m.subagents.filter((a) => a.status === "running").length;
|
|
19487
|
+
const completedAgents = m.subagents.filter((a) => a.status === "completed").length;
|
|
19488
|
+
lines.push(`{grey-fg}Subagents{/grey-fg} {bold}${m.subagents.length}{/bold} ({green-fg}${runningAgents} running{/green-fg}, ${completedAgents} done)`);
|
|
19496
19489
|
}
|
|
19490
|
+
const cacheRate = t.cacheRead + t.input > 0 ? `{grey-fg}Cache{/grey-fg} {bold}${(t.cacheRead / (t.cacheRead + t.input) * 100).toFixed(1)}%{/bold}` : "";
|
|
19491
|
+
lines.push(
|
|
19492
|
+
"",
|
|
19493
|
+
sectionHeader("Tokens", w2),
|
|
19494
|
+
`{grey-fg}In{/grey-fg} {bold}${fmtNum(t.input)}{/bold} {grey-fg}Out{/grey-fg} {bold}${fmtNum(t.output)}{/bold} ${cacheRate} {green-fg}$${t.cost.toFixed(4)}{/green-fg}`
|
|
19495
|
+
);
|
|
19496
|
+
const contextBar = makeColorBar(c.percent, 30, contextColor);
|
|
19497
19497
|
lines.push(
|
|
19498
19498
|
"",
|
|
19499
|
-
"
|
|
19500
|
-
` {
|
|
19499
|
+
sectionHeader("Context", w2),
|
|
19500
|
+
` ${contextBar} {bold}${c.percent}%{/bold} ${fmtNum(c.used)} / ${fmtNum(c.limit)}`
|
|
19501
|
+
);
|
|
19502
|
+
if (m.contextTimeline && m.contextTimeline.length > 1) {
|
|
19503
|
+
const ctxData = m.contextTimeline.slice(-25).map((p) => p.inputTokens);
|
|
19504
|
+
const ctxSpark = makeSparkline(ctxData);
|
|
19505
|
+
lines.push(` {grey-fg}${ctxSpark.spark}{/grey-fg} {grey-fg}peak ${fmtNum(ctxSpark.max)}{/grey-fg}`);
|
|
19506
|
+
}
|
|
19507
|
+
const burnData = m.burnRate.length > 0 ? m.burnRate : [0];
|
|
19508
|
+
const burnSpark = makeSparkline(burnData);
|
|
19509
|
+
lines.push(
|
|
19510
|
+
"",
|
|
19511
|
+
sectionHeader("Burn Rate", w2),
|
|
19512
|
+
` {cyan-fg}${burnSpark.spark}{/cyan-fg} {bold}${fmtNum(burnSpark.latest)}{/bold}{grey-fg} tok/min{/grey-fg} {grey-fg}peak ${fmtNum(burnSpark.max)}{/grey-fg}`
|
|
19501
19513
|
);
|
|
19502
19514
|
if (m.tasks.length > 0) {
|
|
19503
19515
|
const completed = m.tasks.filter((t2) => t2.status === "completed").length;
|
|
19504
19516
|
const active = m.tasks.filter((t2) => t2.status === "in_progress").length;
|
|
19505
19517
|
const pending = m.tasks.filter((t2) => t2.status === "pending").length;
|
|
19506
|
-
lines.push(
|
|
19507
|
-
|
|
19518
|
+
lines.push(
|
|
19519
|
+
"",
|
|
19520
|
+
sectionHeader("Tasks", w2),
|
|
19521
|
+
` {bold}${completed}{/bold}/{m.tasks.length}{grey-fg} completed{/grey-fg} {bold}${active}{/bold}{grey-fg} active{/grey-fg} {bold}${pending}{/bold}{grey-fg} pending{/grey-fg}`
|
|
19522
|
+
);
|
|
19508
19523
|
}
|
|
19509
19524
|
const diffStats = this.diffCache?.getStats() ?? /* @__PURE__ */ new Map();
|
|
19510
19525
|
if (diffStats.size > 0) {
|
|
@@ -19513,25 +19528,28 @@ ${hint}{/grey-fg}`;
|
|
|
19513
19528
|
totalAdd += s2.additions;
|
|
19514
19529
|
totalDel += s2.deletions;
|
|
19515
19530
|
}
|
|
19516
|
-
lines.push(
|
|
19517
|
-
|
|
19531
|
+
lines.push(
|
|
19532
|
+
"",
|
|
19533
|
+
sectionHeader("File Changes", w2),
|
|
19534
|
+
` {bold}${diffStats.size}{/bold}{grey-fg} files{/grey-fg} {green-fg}+${totalAdd}{/green-fg} {red-fg}-${totalDel}{/red-fg}`
|
|
19535
|
+
);
|
|
19518
19536
|
}
|
|
19519
19537
|
if (m.modelStats.length > 0) {
|
|
19520
|
-
lines.push("", "
|
|
19538
|
+
lines.push("", sectionHeader("Model Usage", w2));
|
|
19521
19539
|
for (const ms of m.modelStats) {
|
|
19522
19540
|
const modelName = ms.model.length > 20 ? ms.model.substring(0, 17) + "..." : ms.model;
|
|
19523
|
-
lines.push(` ${modelName.padEnd(20)} ${String(ms.calls).padStart(4)} calls {green-fg}$${ms.cost.toFixed(4)}{/green-fg}`);
|
|
19541
|
+
lines.push(` ${modelName.padEnd(20)} {bold}${String(ms.calls).padStart(4)}{/bold}{grey-fg} calls{/grey-fg} {green-fg}$${ms.cost.toFixed(4)}{/green-fg}`);
|
|
19524
19542
|
}
|
|
19525
19543
|
}
|
|
19526
19544
|
if (m.quota?.available) {
|
|
19527
19545
|
const q = m.quota;
|
|
19528
|
-
lines.push("", "
|
|
19546
|
+
lines.push("", sectionHeader("Quota", w2));
|
|
19529
19547
|
const fiveColor = getUtilizationColor(q.fiveHour.utilization);
|
|
19530
|
-
const fiveBar =
|
|
19531
|
-
lines.push(` 5h
|
|
19548
|
+
const fiveBar = makeColorBar(q.fiveHour.utilization, 18, fiveColor);
|
|
19549
|
+
lines.push(` {grey-fg}5h{/grey-fg} ${fiveBar} {bold}${q.fiveHour.utilization.toFixed(0)}%{/bold}`);
|
|
19532
19550
|
const sevenColor = getUtilizationColor(q.sevenDay.utilization);
|
|
19533
|
-
const sevenBar =
|
|
19534
|
-
lines.push(` 7d
|
|
19551
|
+
const sevenBar = makeColorBar(q.sevenDay.utilization, 18, sevenColor);
|
|
19552
|
+
lines.push(` {grey-fg}7d{/grey-fg} ${sevenBar} {bold}${q.sevenDay.utilization.toFixed(0)}%{/bold}`);
|
|
19535
19553
|
}
|
|
19536
19554
|
const attrLines = renderContextAttribution(m.contextAttribution);
|
|
19537
19555
|
if (attrLines.length > 0) {
|
|
@@ -19540,21 +19558,18 @@ ${hint}{/grey-fg}`;
|
|
|
19540
19558
|
return lines.join("\n");
|
|
19541
19559
|
}
|
|
19542
19560
|
const s = d.session;
|
|
19561
|
+
const w = detailWidth();
|
|
19543
19562
|
const totalTokens = s.inputTokens + s.outputTokens;
|
|
19544
19563
|
return [
|
|
19545
|
-
`{bold}${s.date}{/bold}`,
|
|
19564
|
+
`{bold}${s.date}{/bold} {bold}${s.sessionCount}{/bold}{grey-fg} sessions{/grey-fg} {bold}${s.messageCount}{/bold}{grey-fg} messages{/grey-fg}`,
|
|
19565
|
+
`{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}$${s.totalCost.toFixed(4)}{/green-fg}`,
|
|
19546
19566
|
"",
|
|
19547
|
-
|
|
19548
|
-
`{
|
|
19549
|
-
`{bold}Cost:{/bold} {green-fg}$${s.totalCost.toFixed(4)}{/green-fg}`,
|
|
19550
|
-
`{bold}Messages:{/bold} ${s.messageCount}`,
|
|
19567
|
+
sectionHeader("Models", w),
|
|
19568
|
+
...s.modelUsage.map((u) => ` ${u.model}: {bold}${u.calls}{/bold} calls`),
|
|
19551
19569
|
"",
|
|
19552
|
-
"
|
|
19553
|
-
...s.modelUsage.map((u) => ` ${u.model}: ${u.calls} calls`),
|
|
19554
|
-
"",
|
|
19555
|
-
"{bold}Tools{/bold}",
|
|
19570
|
+
sectionHeader("Tools", w),
|
|
19556
19571
|
...s.toolUsage.sort((a, b) => b.calls - a.calls).slice(0, 10).map(
|
|
19557
|
-
(u) => ` ${u.tool.padEnd(16)} ${u.calls} calls`
|
|
19572
|
+
(u) => ` ${u.tool.padEnd(16)} {bold}${u.calls}{/bold} calls`
|
|
19558
19573
|
)
|
|
19559
19574
|
].join("\n");
|
|
19560
19575
|
}
|
|
@@ -19688,10 +19703,10 @@ ${hint}{/grey-fg}`;
|
|
|
19688
19703
|
const running = agents.filter((a) => a.status === "running").length;
|
|
19689
19704
|
const completed = agents.filter((a) => a.status === "completed").length;
|
|
19690
19705
|
const parallel = agents.filter((a) => a.isParallel).length;
|
|
19706
|
+
const w = detailWidth();
|
|
19691
19707
|
const lines = [
|
|
19692
|
-
"
|
|
19693
|
-
"",
|
|
19694
|
-
` Total: ${agents.length} Running: {green-fg}${running}{/green-fg} Completed: {cyan-fg}${completed}{/cyan-fg}` + (parallel > 0 ? ` Parallel: {magenta-fg}${parallel}{/magenta-fg}` : ""),
|
|
19708
|
+
sectionHeader("Subagents", w),
|
|
19709
|
+
` {bold}${agents.length}{/bold}{grey-fg} total{/grey-fg} {green-fg}{bold}${running}{/bold} running{/green-fg} {cyan-fg}{bold}${completed}{/bold} done{/cyan-fg}` + (parallel > 0 ? ` {magenta-fg}{bold}${parallel}{/bold} parallel{/magenta-fg}` : ""),
|
|
19695
19710
|
""
|
|
19696
19711
|
];
|
|
19697
19712
|
for (const a of agents) {
|
|
@@ -19713,7 +19728,7 @@ ${hint}{/grey-fg}`;
|
|
|
19713
19728
|
}
|
|
19714
19729
|
const subagentTasks = metrics.tasks.filter((t) => t.subagentType);
|
|
19715
19730
|
if (subagentTasks.length > 0) {
|
|
19716
|
-
lines.push("", "
|
|
19731
|
+
lines.push("", sectionHeader("Tasks from Subagents", w), "");
|
|
19717
19732
|
for (const t of subagentTasks) {
|
|
19718
19733
|
const statusIcon = t.status === "completed" ? "\u2713" : t.status === "in_progress" ? "\u2192" : "\u25CB";
|
|
19719
19734
|
const taskPrefix = ` ${statusIcon} ${t.subagentType} #${t.taskId}: `;
|
|
@@ -19756,6 +19771,7 @@ var init_TasksPanel = __esm({
|
|
|
19756
19771
|
id = "tasks";
|
|
19757
19772
|
title = "Tasks";
|
|
19758
19773
|
shortcutKey = 2;
|
|
19774
|
+
emptyStateHint = "Tasks appear as your agent works.";
|
|
19759
19775
|
detailTabs = [
|
|
19760
19776
|
{ label: "Detail", render: (item, m) => this.renderDetail(item, m) }
|
|
19761
19777
|
];
|
|
@@ -19851,6 +19867,7 @@ var init_KanbanPanel = __esm({
|
|
|
19851
19867
|
id = "kanban";
|
|
19852
19868
|
title = "Kanban";
|
|
19853
19869
|
shortcutKey = 3;
|
|
19870
|
+
emptyStateHint = "Task board populates from active sessions.";
|
|
19854
19871
|
detailTabs = [
|
|
19855
19872
|
{ label: "Board", render: (item, m) => this.renderBoard(item, m) }
|
|
19856
19873
|
];
|
|
@@ -19966,6 +19983,7 @@ var init_NotesPanel = __esm({
|
|
|
19966
19983
|
id = "notes";
|
|
19967
19984
|
title = "Notes";
|
|
19968
19985
|
shortcutKey = 4;
|
|
19986
|
+
emptyStateHint = "Knowledge notes saved by your agent appear here.";
|
|
19969
19987
|
detailTabs = [
|
|
19970
19988
|
{ label: "Content", render: (item) => this.renderContent(item) },
|
|
19971
19989
|
{ label: "Related", render: (item, _m, sd) => this.renderRelated(item, sd) }
|
|
@@ -20038,6 +20056,7 @@ var init_DecisionsPanel = __esm({
|
|
|
20038
20056
|
id = "decisions";
|
|
20039
20057
|
title = "Decisions";
|
|
20040
20058
|
shortcutKey = 5;
|
|
20059
|
+
emptyStateHint = "Decisions logged by your agent show up here.";
|
|
20041
20060
|
detailTabs = [
|
|
20042
20061
|
{ label: "Detail", render: (item) => this.renderDetail(item) }
|
|
20043
20062
|
];
|
|
@@ -20123,6 +20142,7 @@ var init_PlansPanel = __esm({
|
|
|
20123
20142
|
id = "plans";
|
|
20124
20143
|
title = "Plans";
|
|
20125
20144
|
shortcutKey = 6;
|
|
20145
|
+
emptyStateHint = "Plans created by your agent appear here.";
|
|
20126
20146
|
sourceFilter = "all";
|
|
20127
20147
|
detailTabs = [
|
|
20128
20148
|
{ label: "Steps", render: (item) => this.renderSteps(item) },
|
|
@@ -31205,14 +31225,14 @@ var require_react_reconciler_production = __commonJS({
|
|
|
31205
31225
|
}
|
|
31206
31226
|
var exports2 = {};
|
|
31207
31227
|
"use strict";
|
|
31208
|
-
var
|
|
31228
|
+
var React16 = require_react(), Scheduler2 = require_scheduler(), assign = Object.assign, REACT_LEGACY_ELEMENT_TYPE = Symbol.for("react.element"), REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), REACT_PORTAL_TYPE = Symbol.for("react.portal"), REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"), REACT_PROFILER_TYPE = Symbol.for("react.profiler"), REACT_CONSUMER_TYPE = Symbol.for("react.consumer"), REACT_CONTEXT_TYPE = Symbol.for("react.context"), REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"), REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"), REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"), REACT_MEMO_TYPE = Symbol.for("react.memo"), REACT_LAZY_TYPE = Symbol.for("react.lazy");
|
|
31209
31229
|
Symbol.for("react.scope");
|
|
31210
31230
|
var REACT_ACTIVITY_TYPE = Symbol.for("react.activity");
|
|
31211
31231
|
Symbol.for("react.legacy_hidden");
|
|
31212
31232
|
Symbol.for("react.tracing_marker");
|
|
31213
31233
|
var REACT_MEMO_CACHE_SENTINEL = Symbol.for("react.memo_cache_sentinel");
|
|
31214
31234
|
Symbol.for("react.view_transition");
|
|
31215
|
-
var MAYBE_ITERATOR_SYMBOL = Symbol.iterator, REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"), isArrayImpl = Array.isArray, ReactSharedInternals =
|
|
31235
|
+
var MAYBE_ITERATOR_SYMBOL = Symbol.iterator, REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"), isArrayImpl = Array.isArray, ReactSharedInternals = React16.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, rendererVersion = $$$config.rendererVersion, rendererPackageName = $$$config.rendererPackageName, extraDevToolsConfig = $$$config.extraDevToolsConfig, getPublicInstance = $$$config.getPublicInstance, getRootHostContext = $$$config.getRootHostContext, getChildHostContext = $$$config.getChildHostContext, prepareForCommit = $$$config.prepareForCommit, resetAfterCommit = $$$config.resetAfterCommit, createInstance = $$$config.createInstance;
|
|
31216
31236
|
$$$config.cloneMutableInstance;
|
|
31217
31237
|
var appendInitialChild = $$$config.appendInitialChild, finalizeInitialChildren = $$$config.finalizeInitialChildren, shouldSetTextContent = $$$config.shouldSetTextContent, createTextInstance = $$$config.createTextInstance;
|
|
31218
31238
|
$$$config.cloneMutableTextInstance;
|
|
@@ -43805,14 +43825,14 @@ var require_react_reconciler_development = __commonJS({
|
|
|
43805
43825
|
}
|
|
43806
43826
|
var exports2 = {};
|
|
43807
43827
|
"use strict";
|
|
43808
|
-
var
|
|
43828
|
+
var React16 = require_react(), Scheduler2 = require_scheduler(), assign = Object.assign, REACT_LEGACY_ELEMENT_TYPE = Symbol.for("react.element"), REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), REACT_PORTAL_TYPE = Symbol.for("react.portal"), REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"), REACT_PROFILER_TYPE = Symbol.for("react.profiler"), REACT_CONSUMER_TYPE = Symbol.for("react.consumer"), REACT_CONTEXT_TYPE = Symbol.for("react.context"), REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"), REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"), REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"), REACT_MEMO_TYPE = Symbol.for("react.memo"), REACT_LAZY_TYPE = Symbol.for("react.lazy");
|
|
43809
43829
|
Symbol.for("react.scope");
|
|
43810
43830
|
var REACT_ACTIVITY_TYPE = Symbol.for("react.activity");
|
|
43811
43831
|
Symbol.for("react.legacy_hidden");
|
|
43812
43832
|
Symbol.for("react.tracing_marker");
|
|
43813
43833
|
var REACT_MEMO_CACHE_SENTINEL = Symbol.for("react.memo_cache_sentinel");
|
|
43814
43834
|
Symbol.for("react.view_transition");
|
|
43815
|
-
var MAYBE_ITERATOR_SYMBOL = Symbol.iterator, REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"), isArrayImpl = Array.isArray, ReactSharedInternals =
|
|
43835
|
+
var MAYBE_ITERATOR_SYMBOL = Symbol.iterator, REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"), isArrayImpl = Array.isArray, ReactSharedInternals = React16.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, rendererVersion = $$$config.rendererVersion, rendererPackageName = $$$config.rendererPackageName, extraDevToolsConfig = $$$config.extraDevToolsConfig, getPublicInstance = $$$config.getPublicInstance, getRootHostContext = $$$config.getRootHostContext, getChildHostContext = $$$config.getChildHostContext, prepareForCommit = $$$config.prepareForCommit, resetAfterCommit = $$$config.resetAfterCommit, createInstance = $$$config.createInstance;
|
|
43816
43836
|
$$$config.cloneMutableInstance;
|
|
43817
43837
|
var appendInitialChild = $$$config.appendInitialChild, finalizeInitialChildren = $$$config.finalizeInitialChildren, shouldSetTextContent = $$$config.shouldSetTextContent, createTextInstance = $$$config.createTextInstance;
|
|
43818
43838
|
$$$config.cloneMutableTextInstance;
|
|
@@ -57472,18 +57492,18 @@ var require_react_jsx_runtime_development = __commonJS({
|
|
|
57472
57492
|
function isValidElement(object) {
|
|
57473
57493
|
return "object" === typeof object && null !== object && object.$$typeof === REACT_ELEMENT_TYPE;
|
|
57474
57494
|
}
|
|
57475
|
-
var
|
|
57495
|
+
var React16 = require_react(), REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), REACT_PORTAL_TYPE = Symbol.for("react.portal"), REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"), REACT_PROFILER_TYPE = Symbol.for("react.profiler"), REACT_CONSUMER_TYPE = Symbol.for("react.consumer"), REACT_CONTEXT_TYPE = Symbol.for("react.context"), REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"), REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"), REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"), REACT_MEMO_TYPE = Symbol.for("react.memo"), REACT_LAZY_TYPE = Symbol.for("react.lazy"), REACT_ACTIVITY_TYPE = Symbol.for("react.activity"), REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"), ReactSharedInternals = React16.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, hasOwnProperty = Object.prototype.hasOwnProperty, isArrayImpl = Array.isArray, createTask = console.createTask ? console.createTask : function() {
|
|
57476
57496
|
return null;
|
|
57477
57497
|
};
|
|
57478
|
-
|
|
57498
|
+
React16 = {
|
|
57479
57499
|
react_stack_bottom_frame: function(callStackForError) {
|
|
57480
57500
|
return callStackForError();
|
|
57481
57501
|
}
|
|
57482
57502
|
};
|
|
57483
57503
|
var specialPropKeyWarningShown;
|
|
57484
57504
|
var didWarnAboutElementRef = {};
|
|
57485
|
-
var unknownOwnerDebugStack =
|
|
57486
|
-
|
|
57505
|
+
var unknownOwnerDebugStack = React16.react_stack_bottom_frame.bind(
|
|
57506
|
+
React16,
|
|
57487
57507
|
UnknownOwner
|
|
57488
57508
|
)();
|
|
57489
57509
|
var unknownOwnerDebugTask = createTask(getTaskName(UnknownOwner));
|
|
@@ -57528,9 +57548,29 @@ var require_jsx_runtime = __commonJS({
|
|
|
57528
57548
|
});
|
|
57529
57549
|
|
|
57530
57550
|
// src/dashboard/ink/SessionPickerInk.tsx
|
|
57551
|
+
function buildGroupedRows(items) {
|
|
57552
|
+
const providerIds = new Set(items.map((it) => it.providerId).filter(Boolean));
|
|
57553
|
+
if (providerIds.size <= 1) return null;
|
|
57554
|
+
const rows = [];
|
|
57555
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
57556
|
+
for (let i = 0; i < items.length; i++) {
|
|
57557
|
+
const pid = items[i].providerId || "unknown";
|
|
57558
|
+
if (!grouped.has(pid)) grouped.set(pid, []);
|
|
57559
|
+
grouped.get(pid).push(i);
|
|
57560
|
+
}
|
|
57561
|
+
for (const [pid, indices] of grouped) {
|
|
57562
|
+
rows.push({ type: "header", providerId: pid });
|
|
57563
|
+
for (const idx of indices) {
|
|
57564
|
+
rows.push({ type: "item", index: idx });
|
|
57565
|
+
}
|
|
57566
|
+
}
|
|
57567
|
+
rows.push({ type: "item", index: items.length });
|
|
57568
|
+
return { rows, selectableCount: items.length + 1 };
|
|
57569
|
+
}
|
|
57531
57570
|
function SessionPickerInk({ items, onSelect }) {
|
|
57532
57571
|
const [selectedIndex, setSelectedIndex] = (0, import_react29.useState)(0);
|
|
57533
57572
|
const { exit } = use_app_default();
|
|
57573
|
+
const grouped = buildGroupedRows(items);
|
|
57534
57574
|
const totalItems = items.length + 1;
|
|
57535
57575
|
use_input_default((input, key) => {
|
|
57536
57576
|
if (input === "q" || key.escape || key.ctrl && input === "c") {
|
|
@@ -57556,9 +57596,88 @@ function SessionPickerInk({ items, onSelect }) {
|
|
|
57556
57596
|
});
|
|
57557
57597
|
const rows = process.stdout.rows || 24;
|
|
57558
57598
|
const viewportHeight = Math.max(5, rows - 15);
|
|
57559
|
-
|
|
57560
|
-
|
|
57561
|
-
|
|
57599
|
+
function renderSessionRow(i, isSelected) {
|
|
57600
|
+
if (i === items.length) {
|
|
57601
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { inverse: isSelected, children: [
|
|
57602
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "yellow", children: "+" }),
|
|
57603
|
+
" Wait for a new session to start..."
|
|
57604
|
+
] }) }, "wait");
|
|
57605
|
+
}
|
|
57606
|
+
const item = items[i];
|
|
57607
|
+
const dot = item.isActive ? "\u25CF" : "\u25CB";
|
|
57608
|
+
const dotColor = item.isActive ? "green" : "gray";
|
|
57609
|
+
const badge = item.providerId ? PROVIDER_BADGES[item.providerId] : null;
|
|
57610
|
+
const truncLabel = item.label.length > 40 ? item.label.substring(0, 37) + "..." : item.label;
|
|
57611
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { inverse: isSelected, children: [
|
|
57612
|
+
badge && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { color: badge.color, children: [
|
|
57613
|
+
"[",
|
|
57614
|
+
badge.badge,
|
|
57615
|
+
"]"
|
|
57616
|
+
] }),
|
|
57617
|
+
" ",
|
|
57618
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: dotColor, children: dot }),
|
|
57619
|
+
" ",
|
|
57620
|
+
truncLabel.padEnd(40),
|
|
57621
|
+
" ",
|
|
57622
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "gray", children: item.age.padEnd(9) }),
|
|
57623
|
+
" ",
|
|
57624
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "gray", children: item.sessionId }),
|
|
57625
|
+
item.isActive ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "green", children: " LIVE" }) : ""
|
|
57626
|
+
] }) }, item.sessionPath);
|
|
57627
|
+
}
|
|
57628
|
+
function renderList() {
|
|
57629
|
+
if (grouped) {
|
|
57630
|
+
const allRows = grouped.rows;
|
|
57631
|
+
let selectableIdx = 0;
|
|
57632
|
+
const selectablePositions = [];
|
|
57633
|
+
for (let r = 0; r < allRows.length; r++) {
|
|
57634
|
+
if (allRows[r].type === "item") selectablePositions.push(r);
|
|
57635
|
+
}
|
|
57636
|
+
const selectedVisualPos = selectablePositions[selectedIndex] ?? 0;
|
|
57637
|
+
const scrollOffset2 = Math.max(0, Math.min(selectedVisualPos - Math.floor(viewportHeight / 2), allRows.length - viewportHeight));
|
|
57638
|
+
const visibleStart2 = Math.max(0, scrollOffset2);
|
|
57639
|
+
const visibleEnd2 = Math.min(allRows.length, visibleStart2 + viewportHeight);
|
|
57640
|
+
const elements = [];
|
|
57641
|
+
selectableIdx = 0;
|
|
57642
|
+
for (let r = 0; r < allRows.length; r++) {
|
|
57643
|
+
if (r < visibleStart2 || r >= visibleEnd2) {
|
|
57644
|
+
if (allRows[r].type === "item") selectableIdx++;
|
|
57645
|
+
continue;
|
|
57646
|
+
}
|
|
57647
|
+
const row = allRows[r];
|
|
57648
|
+
if (row.type === "header") {
|
|
57649
|
+
const name = PROVIDER_NAMES[row.providerId] || row.providerId;
|
|
57650
|
+
const badge = PROVIDER_BADGES[row.providerId];
|
|
57651
|
+
elements.push(
|
|
57652
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { children: [
|
|
57653
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { dimColor: true, children: [
|
|
57654
|
+
"\u2500\u2500",
|
|
57655
|
+
" "
|
|
57656
|
+
] }),
|
|
57657
|
+
badge && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: badge.color, children: name }),
|
|
57658
|
+
!badge && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: name }),
|
|
57659
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { dimColor: true, children: [
|
|
57660
|
+
" ",
|
|
57661
|
+
"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"
|
|
57662
|
+
] })
|
|
57663
|
+
] }, `hdr-${row.providerId}`)
|
|
57664
|
+
);
|
|
57665
|
+
} else {
|
|
57666
|
+
const isSelected = selectableIdx === selectedIndex;
|
|
57667
|
+
elements.push(renderSessionRow(row.index, isSelected));
|
|
57668
|
+
selectableIdx++;
|
|
57669
|
+
}
|
|
57670
|
+
}
|
|
57671
|
+
return elements;
|
|
57672
|
+
}
|
|
57673
|
+
const scrollOffset = Math.max(0, Math.min(selectedIndex - Math.floor(viewportHeight / 2), totalItems - viewportHeight));
|
|
57674
|
+
const visibleStart = Math.max(0, scrollOffset);
|
|
57675
|
+
const visibleEnd = Math.min(totalItems, visibleStart + viewportHeight);
|
|
57676
|
+
return Array.from({ length: visibleEnd - visibleStart }, (_, vi) => {
|
|
57677
|
+
const i = visibleStart + vi;
|
|
57678
|
+
return renderSessionRow(i, i === selectedIndex);
|
|
57679
|
+
});
|
|
57680
|
+
}
|
|
57562
57681
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { flexDirection: "column", width: "100%", height: rows, children: [
|
|
57563
57682
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box_default, { justifyContent: "center", marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { flexDirection: "column", width: 50, children: [
|
|
57564
57683
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { bold: true, color: "magenta", children: " S I D E K I C K" }),
|
|
@@ -57578,37 +57697,7 @@ function SessionPickerInk({ items, onSelect }) {
|
|
|
57578
57697
|
items.length,
|
|
57579
57698
|
") "
|
|
57580
57699
|
] }),
|
|
57581
|
-
|
|
57582
|
-
const i = visibleStart + vi;
|
|
57583
|
-
const isSelected = i === selectedIndex;
|
|
57584
|
-
if (i === items.length) {
|
|
57585
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { inverse: isSelected, children: [
|
|
57586
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "yellow", children: "+" }),
|
|
57587
|
-
" Wait for a new session to start..."
|
|
57588
|
-
] }) }, "wait");
|
|
57589
|
-
}
|
|
57590
|
-
const item = items[i];
|
|
57591
|
-
const dot = item.isActive ? "\u25CF" : "\u25CB";
|
|
57592
|
-
const dotColor = item.isActive ? "green" : "gray";
|
|
57593
|
-
const badge = item.providerId ? PROVIDER_BADGES[item.providerId] : null;
|
|
57594
|
-
const truncLabel = item.label.length > 40 ? item.label.substring(0, 37) + "..." : item.label;
|
|
57595
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { inverse: isSelected, children: [
|
|
57596
|
-
badge && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { color: badge.color, children: [
|
|
57597
|
-
"[",
|
|
57598
|
-
badge.badge,
|
|
57599
|
-
"]"
|
|
57600
|
-
] }),
|
|
57601
|
-
" ",
|
|
57602
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: dotColor, children: dot }),
|
|
57603
|
-
" ",
|
|
57604
|
-
truncLabel.padEnd(40),
|
|
57605
|
-
" ",
|
|
57606
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "gray", children: item.age.padEnd(9) }),
|
|
57607
|
-
" ",
|
|
57608
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "gray", children: item.sessionId }),
|
|
57609
|
-
item.isActive ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "green", children: " LIVE" }) : ""
|
|
57610
|
-
] }) }, item.sessionPath);
|
|
57611
|
-
})
|
|
57700
|
+
renderList()
|
|
57612
57701
|
]
|
|
57613
57702
|
}
|
|
57614
57703
|
),
|
|
@@ -57618,7 +57707,11 @@ function SessionPickerInk({ items, onSelect }) {
|
|
|
57618
57707
|
" ",
|
|
57619
57708
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "gray", children: "Session Picker" }),
|
|
57620
57709
|
" ",
|
|
57621
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
57710
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { bold: true, children: [
|
|
57711
|
+
"\u2191",
|
|
57712
|
+
"/",
|
|
57713
|
+
"\u2193"
|
|
57714
|
+
] }),
|
|
57622
57715
|
" navigate ",
|
|
57623
57716
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { bold: true, children: "Enter" }),
|
|
57624
57717
|
" select ",
|
|
@@ -57658,7 +57751,7 @@ async function showSessionPicker(provider, workspacePath, additionalProviders) {
|
|
|
57658
57751
|
}).catch(reject);
|
|
57659
57752
|
});
|
|
57660
57753
|
}
|
|
57661
|
-
var import_react29, import_jsx_runtime;
|
|
57754
|
+
var import_react29, import_jsx_runtime, PROVIDER_NAMES;
|
|
57662
57755
|
var init_SessionPickerInk = __esm({
|
|
57663
57756
|
async "src/dashboard/ink/SessionPickerInk.tsx"() {
|
|
57664
57757
|
"use strict";
|
|
@@ -57666,6 +57759,11 @@ var init_SessionPickerInk = __esm({
|
|
|
57666
57759
|
await init_build2();
|
|
57667
57760
|
init_SessionPickerHelpers();
|
|
57668
57761
|
import_jsx_runtime = __toESM(require_jsx_runtime(), 1);
|
|
57762
|
+
PROVIDER_NAMES = {
|
|
57763
|
+
"claude-code": "Claude Code",
|
|
57764
|
+
"opencode": "OpenCode",
|
|
57765
|
+
"codex": "Codex"
|
|
57766
|
+
};
|
|
57669
57767
|
}
|
|
57670
57768
|
});
|
|
57671
57769
|
|
|
@@ -57809,27 +57907,27 @@ var init_useWindowedScroll = __esm({
|
|
|
57809
57907
|
// src/dashboard/ink/TabBar.tsx
|
|
57810
57908
|
function TabBar({ panels, activeIndex, layoutMode }) {
|
|
57811
57909
|
const modeLabel = MODE_LABELS[layoutMode] || layoutMode;
|
|
57812
|
-
const modeColor = MODE_COLORS[layoutMode] || "gray";
|
|
57813
57910
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { height: 1, width: "100%", children: [
|
|
57814
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Box_default, { flexGrow: 1, children: panels.map((p, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Box_default, { marginRight: 1, children: i === activeIndex ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { bold: true, color: "magenta", children: [
|
|
57815
|
-
"[",
|
|
57911
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Box_default, { flexGrow: 1, children: panels.map((p, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Box_default, { marginRight: 1, children: i === activeIndex ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { bold: true, underline: true, color: "magenta", children: [
|
|
57816
57912
|
p.shortcutKey,
|
|
57817
|
-
"
|
|
57818
|
-
p.title
|
|
57819
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { color: "gray", children: [
|
|
57820
|
-
"[",
|
|
57821
|
-
p.shortcutKey,
|
|
57822
|
-
"] ",
|
|
57913
|
+
" ",
|
|
57823
57914
|
p.title
|
|
57915
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
57916
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { dimColor: true, children: p.shortcutKey }),
|
|
57917
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { color: "gray", children: [
|
|
57918
|
+
" ",
|
|
57919
|
+
p.title
|
|
57920
|
+
] })
|
|
57824
57921
|
] }) }, p.id)) }),
|
|
57825
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, {
|
|
57922
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { dimColor: true, children: [
|
|
57826
57923
|
"z: ",
|
|
57827
57924
|
modeLabel,
|
|
57828
|
-
"
|
|
57925
|
+
" ",
|
|
57926
|
+
"\u25B8"
|
|
57829
57927
|
] }) })
|
|
57830
57928
|
] });
|
|
57831
57929
|
}
|
|
57832
|
-
var import_jsx_runtime2, MODE_LABELS
|
|
57930
|
+
var import_jsx_runtime2, MODE_LABELS;
|
|
57833
57931
|
var init_TabBar = __esm({
|
|
57834
57932
|
async "src/dashboard/ink/TabBar.tsx"() {
|
|
57835
57933
|
"use strict";
|
|
@@ -57840,11 +57938,6 @@ var init_TabBar = __esm({
|
|
|
57840
57938
|
expanded: "Expanded",
|
|
57841
57939
|
"wide-side": "Wide Side"
|
|
57842
57940
|
};
|
|
57843
|
-
MODE_COLORS = {
|
|
57844
|
-
normal: "gray",
|
|
57845
|
-
expanded: "cyan",
|
|
57846
|
-
"wide-side": "yellow"
|
|
57847
|
-
};
|
|
57848
57941
|
}
|
|
57849
57942
|
});
|
|
57850
57943
|
|
|
@@ -57955,9 +58048,11 @@ function SideList({
|
|
|
57955
58048
|
width,
|
|
57956
58049
|
viewportHeight,
|
|
57957
58050
|
panelTitle,
|
|
57958
|
-
sessionFilterActive
|
|
58051
|
+
sessionFilterActive,
|
|
58052
|
+
emptyStateHint
|
|
57959
58053
|
}) {
|
|
57960
58054
|
const borderColor = focused ? "magenta" : "gray";
|
|
58055
|
+
const borderStyle = focused ? "double" : "single";
|
|
57961
58056
|
const innerWidth = Math.max(1, width - 3);
|
|
57962
58057
|
const visibleItems = items.slice(scrollOffset, scrollOffset + viewportHeight);
|
|
57963
58058
|
const hasMoreAbove = scrollOffset > 0;
|
|
@@ -57967,7 +58062,7 @@ function SideList({
|
|
|
57967
58062
|
{
|
|
57968
58063
|
width,
|
|
57969
58064
|
flexDirection: "column",
|
|
57970
|
-
borderStyle
|
|
58065
|
+
borderStyle,
|
|
57971
58066
|
borderColor,
|
|
57972
58067
|
overflow: "hidden",
|
|
57973
58068
|
children: [
|
|
@@ -58001,9 +58096,10 @@ function SideList({
|
|
|
58001
58096
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: "gray", children: "Press " }),
|
|
58002
58097
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: "magenta", bold: true, children: "f" }),
|
|
58003
58098
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: "gray", children: " to see all" })
|
|
58004
|
-
] }, "empty-hint-2")
|
|
58099
|
+
] }, "empty-hint-2"),
|
|
58100
|
+
!sessionFilterActive && emptyStateHint && viewportHeight >= 5 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Box_default, { justifyContent: "center", width: innerWidth, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { dimColor: true, children: emptyStateHint }) }, "empty-hint-desc")
|
|
58005
58101
|
] }),
|
|
58006
|
-
visibleItems.length < viewportHeight && Array.from({ length: Math.max(0, viewportHeight - visibleItems.length - (items.length === 0 && viewportHeight >= 3 ? sessionFilterActive ? 3 : 2 : 0)) }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Box_default, { width: innerWidth, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { children: " " }) }, `empty-${i}`)),
|
|
58102
|
+
visibleItems.length < viewportHeight && Array.from({ length: Math.max(0, viewportHeight - visibleItems.length - (items.length === 0 && viewportHeight >= 3 ? sessionFilterActive ? 3 : !sessionFilterActive && emptyStateHint && viewportHeight >= 5 ? 3 : 2 : 0)) }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Box_default, { width: innerWidth, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { children: " " }) }, `empty-${i}`)),
|
|
58007
58103
|
hasMoreBelow && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Box_default, { justifyContent: "center", width: innerWidth, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: "gray", children: "\u25BC" }) })
|
|
58008
58104
|
]
|
|
58009
58105
|
}
|
|
@@ -58054,6 +58150,7 @@ function DetailPane({
|
|
|
58054
58150
|
focused
|
|
58055
58151
|
}) {
|
|
58056
58152
|
const borderColor = focused ? "magenta" : "gray";
|
|
58153
|
+
const borderStyle = focused ? "double" : "single";
|
|
58057
58154
|
const lines = content ? content.split("\n") : [];
|
|
58058
58155
|
const totalLines = lines.length;
|
|
58059
58156
|
const hasMoreAbove = scrollOffset > 0;
|
|
@@ -58067,7 +58164,7 @@ function DetailPane({
|
|
|
58067
58164
|
{
|
|
58068
58165
|
flexDirection: "column",
|
|
58069
58166
|
flexGrow: 1,
|
|
58070
|
-
borderStyle
|
|
58167
|
+
borderStyle,
|
|
58071
58168
|
borderColor,
|
|
58072
58169
|
paddingLeft: 1,
|
|
58073
58170
|
children: [
|
|
@@ -58114,64 +58211,88 @@ function StatusBar({
|
|
|
58114
58211
|
const permissionColor = permissionMode === "bypassPermissions" ? "red" : permissionMode === "acceptEdits" ? "magenta" : permissionMode === "plan" ? "green" : void 0;
|
|
58115
58212
|
const permissionLabel = permissionMode === "bypassPermissions" ? "BYPASS" : permissionMode === "acceptEdits" ? "EDITS" : permissionMode === "plan" ? "PLAN" : void 0;
|
|
58116
58213
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Box_default, { height: 1, width: "100%", children: [
|
|
58117
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.
|
|
58118
|
-
|
|
58119
|
-
|
|
58120
|
-
|
|
58121
|
-
|
|
58122
|
-
|
|
58123
|
-
|
|
58124
|
-
|
|
58125
|
-
|
|
58126
|
-
|
|
58127
|
-
|
|
58128
|
-
|
|
58129
|
-
|
|
58130
|
-
|
|
58131
|
-
permissionMode && permissionMode !== "default" && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
58132
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: "gray", children: " | " }),
|
|
58133
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: permissionColor, children: permissionLabel })
|
|
58134
|
-
] }),
|
|
58135
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: "gray", children: " | " }),
|
|
58136
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: evtLabel }),
|
|
58137
|
-
filterString && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { color: "yellow", children: [
|
|
58138
|
-
' filter: "',
|
|
58139
|
-
filterString,
|
|
58140
|
-
'" (',
|
|
58141
|
-
matchCount ?? 0,
|
|
58142
|
-
" of ",
|
|
58143
|
-
totalCount ?? 0,
|
|
58144
|
-
")"
|
|
58214
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Box_default, { children: [
|
|
58215
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { bold: true, color: "magenta", children: [
|
|
58216
|
+
"\u26A1",
|
|
58217
|
+
" SIDEKICK"
|
|
58218
|
+
] }),
|
|
58219
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { dimColor: true, children: [
|
|
58220
|
+
" v",
|
|
58221
|
+
"0.12.8"
|
|
58222
|
+
] }),
|
|
58223
|
+
updateInfo && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { color: "yellow", children: [
|
|
58224
|
+
" (v",
|
|
58225
|
+
updateInfo.latest,
|
|
58226
|
+
")"
|
|
58227
|
+
] })
|
|
58145
58228
|
] }),
|
|
58146
|
-
|
|
58147
|
-
|
|
58148
|
-
|
|
58229
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Box_default, { flexGrow: 1, justifyContent: "center", children: [
|
|
58230
|
+
providerName && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
58231
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { dimColor: true, children: [
|
|
58232
|
+
" ",
|
|
58233
|
+
"\u2502",
|
|
58234
|
+
" "
|
|
58235
|
+
] }),
|
|
58236
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: "cyan", children: providerName })
|
|
58237
|
+
] }),
|
|
58238
|
+
permissionMode && permissionMode !== "default" && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
58239
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { dimColor: true, children: [
|
|
58240
|
+
" ",
|
|
58241
|
+
"\u2502",
|
|
58242
|
+
" "
|
|
58243
|
+
] }),
|
|
58244
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: permissionColor, children: permissionLabel })
|
|
58245
|
+
] }),
|
|
58246
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { dimColor: true, children: [
|
|
58247
|
+
" ",
|
|
58248
|
+
"\u2502",
|
|
58249
|
+
" "
|
|
58250
|
+
] }),
|
|
58251
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: evtLabel }),
|
|
58252
|
+
filterString && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { color: "yellow", children: [
|
|
58253
|
+
' filter: "',
|
|
58254
|
+
filterString,
|
|
58255
|
+
'" (',
|
|
58256
|
+
matchCount ?? 0,
|
|
58257
|
+
"/",
|
|
58258
|
+
totalCount ?? 0,
|
|
58259
|
+
")"
|
|
58260
|
+
] }),
|
|
58261
|
+
sessionFilter && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { color: "magenta", children: [
|
|
58262
|
+
" ",
|
|
58263
|
+
sessionFilter
|
|
58264
|
+
] })
|
|
58149
58265
|
] }),
|
|
58150
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.
|
|
58151
|
-
|
|
58152
|
-
|
|
58153
|
-
|
|
58154
|
-
|
|
58155
|
-
"
|
|
58156
|
-
|
|
58157
|
-
|
|
58158
|
-
|
|
58159
|
-
|
|
58160
|
-
|
|
58161
|
-
|
|
58162
|
-
|
|
58163
|
-
|
|
58164
|
-
|
|
58165
|
-
|
|
58166
|
-
|
|
58167
|
-
|
|
58168
|
-
|
|
58169
|
-
|
|
58170
|
-
|
|
58171
|
-
|
|
58172
|
-
|
|
58173
|
-
|
|
58174
|
-
|
|
58266
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Box_default, { children: [
|
|
58267
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { dimColor: true, children: [
|
|
58268
|
+
"\u2502",
|
|
58269
|
+
" "
|
|
58270
|
+
] }),
|
|
58271
|
+
focusTarget === "side" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { children: [
|
|
58272
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, children: "\u2191\u2193" }),
|
|
58273
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { dimColor: true, children: " nav " }),
|
|
58274
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, children: "Tab" }),
|
|
58275
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { dimColor: true, children: " detail " }),
|
|
58276
|
+
panelHints,
|
|
58277
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, children: "/" }),
|
|
58278
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { dimColor: true, children: " filter " }),
|
|
58279
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, children: "?" }),
|
|
58280
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { dimColor: true, children: " help " }),
|
|
58281
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, children: "q" }),
|
|
58282
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { dimColor: true, children: " quit" })
|
|
58283
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { children: [
|
|
58284
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, children: "j/k" }),
|
|
58285
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { dimColor: true, children: " scroll " }),
|
|
58286
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, children: "[]" }),
|
|
58287
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { dimColor: true, children: " tab " }),
|
|
58288
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, children: "Tab" }),
|
|
58289
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { dimColor: true, children: " side " }),
|
|
58290
|
+
panelHints,
|
|
58291
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, children: "?" }),
|
|
58292
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { dimColor: true, children: " help " }),
|
|
58293
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, children: "q" }),
|
|
58294
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { dimColor: true, children: " quit" })
|
|
58295
|
+
] })
|
|
58175
58296
|
] })
|
|
58176
58297
|
] });
|
|
58177
58298
|
}
|
|
@@ -58205,6 +58326,27 @@ var init_useSpinner = __esm({
|
|
|
58205
58326
|
}
|
|
58206
58327
|
});
|
|
58207
58328
|
|
|
58329
|
+
// src/dashboard/branding.ts
|
|
58330
|
+
var LOGO_ART, HELP_HEADER;
|
|
58331
|
+
var init_branding = __esm({
|
|
58332
|
+
"src/dashboard/branding.ts"() {
|
|
58333
|
+
"use strict";
|
|
58334
|
+
init_phraseFormatters();
|
|
58335
|
+
LOGO_ART = [
|
|
58336
|
+
" {yellow-fg}\u26A1{/yellow-fg}",
|
|
58337
|
+
" {magenta-fg}\u2502{/magenta-fg}",
|
|
58338
|
+
" {white-fg}</>{/white-fg} {white-fg}\u256D\u2500\u2500\u2534\u2500\u2500\u256E{/white-fg} {bold}{magenta-fg}S I D E K I C K{/magenta-fg}{/bold}",
|
|
58339
|
+
" {white-fg}\u2502{/white-fg} {cyan-fg}\u25CF{/cyan-fg} {cyan-fg}\u25CF{/cyan-fg} {white-fg}\u2502{/white-fg} {bold}Agent Hub{/bold}",
|
|
58340
|
+
" {white-fg}\u2502{/white-fg} {green-fg}\u25E1{/green-fg} {white-fg}\u2502{/white-fg} {grey-fg}Terminal Dashboard{/grey-fg}",
|
|
58341
|
+
" {white-fg}\u2570\u2500\u2500\u2500\u2500\u2500\u256F{/white-fg}"
|
|
58342
|
+
];
|
|
58343
|
+
HELP_HEADER = [
|
|
58344
|
+
...LOGO_ART,
|
|
58345
|
+
""
|
|
58346
|
+
];
|
|
58347
|
+
}
|
|
58348
|
+
});
|
|
58349
|
+
|
|
58208
58350
|
// src/dashboard/ink/SplashOverlay.tsx
|
|
58209
58351
|
function SplashOverlay() {
|
|
58210
58352
|
const spinner = useSpinner();
|
|
@@ -58218,12 +58360,7 @@ function SplashOverlay() {
|
|
|
58218
58360
|
paddingY: 1,
|
|
58219
58361
|
width: 60,
|
|
58220
58362
|
children: [
|
|
58221
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, {
|
|
58222
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { bold: true, children: " Agent Hub" }),
|
|
58223
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Text, { color: "gray", children: [
|
|
58224
|
-
" Terminal Dashboard",
|
|
58225
|
-
"0.12.7" ? ` v${"0.12.7"}` : ""
|
|
58226
|
-
] }),
|
|
58363
|
+
LOGO_ART.map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { children: parseBlessedTags(line) }, i)),
|
|
58227
58364
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { children: " " }),
|
|
58228
58365
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Text, { color: "gray", children: [
|
|
58229
58366
|
" ",
|
|
@@ -58269,11 +58406,27 @@ var init_SplashOverlay = __esm({
|
|
|
58269
58406
|
await init_build2();
|
|
58270
58407
|
init_useSpinner();
|
|
58271
58408
|
import_sidekick_shared8 = __toESM(require_dist(), 1);
|
|
58409
|
+
init_branding();
|
|
58410
|
+
await init_parseBlessedTags();
|
|
58272
58411
|
import_jsx_runtime8 = __toESM(require_jsx_runtime(), 1);
|
|
58273
58412
|
}
|
|
58274
58413
|
});
|
|
58275
58414
|
|
|
58276
58415
|
// src/dashboard/ink/HelpOverlay.tsx
|
|
58416
|
+
function helpRow(key, desc, keyWidth = 14, totalWidth = 54) {
|
|
58417
|
+
const padding = keyWidth - key.length;
|
|
58418
|
+
const dotCount = Math.max(1, totalWidth - keyWidth - desc.length);
|
|
58419
|
+
const dots = "\xB7".repeat(dotCount);
|
|
58420
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { children: [
|
|
58421
|
+
" ",
|
|
58422
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { bold: true, children: key }),
|
|
58423
|
+
" ".repeat(Math.max(0, padding)),
|
|
58424
|
+
" ",
|
|
58425
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { dimColor: true, children: dots }),
|
|
58426
|
+
" ",
|
|
58427
|
+
desc
|
|
58428
|
+
] });
|
|
58429
|
+
}
|
|
58277
58430
|
function HelpOverlay({ panels, activePanelIndex }) {
|
|
58278
58431
|
const panel = panels[activePanelIndex];
|
|
58279
58432
|
const actions = panel.getActions();
|
|
@@ -58288,75 +58441,25 @@ function HelpOverlay({ panels, activePanelIndex }) {
|
|
|
58288
58441
|
paddingY: 1,
|
|
58289
58442
|
width: 60,
|
|
58290
58443
|
children: [
|
|
58291
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, {
|
|
58292
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { bold: true, children: " Agent Hub" }),
|
|
58444
|
+
LOGO_ART.map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { children: parseBlessedTags(line) }, `logo-${i}`)),
|
|
58293
58445
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { children: " " }),
|
|
58294
58446
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { bold: true, children: " Panels" }),
|
|
58295
|
-
panels.map((p) =>
|
|
58296
|
-
" ",
|
|
58297
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { bold: true, children: p.shortcutKey }),
|
|
58298
|
-
" ",
|
|
58299
|
-
p.title
|
|
58300
|
-
] }, p.id)),
|
|
58447
|
+
panels.map((p) => helpRow(String(p.shortcutKey), p.title)),
|
|
58301
58448
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { children: " " }),
|
|
58302
58449
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { bold: true, children: " Navigation" }),
|
|
58303
|
-
|
|
58304
|
-
|
|
58305
|
-
|
|
58306
|
-
|
|
58307
|
-
|
|
58308
|
-
|
|
58309
|
-
|
|
58310
|
-
|
|
58311
|
-
" Next item (side) / scroll (detail)"
|
|
58312
|
-
] }),
|
|
58313
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { children: [
|
|
58314
|
-
" ",
|
|
58315
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { bold: true, children: "k / \u2191" }),
|
|
58316
|
-
" Prev item (side) / scroll (detail)"
|
|
58317
|
-
] }),
|
|
58318
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { children: [
|
|
58319
|
-
" ",
|
|
58320
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { bold: true, children: "g / G" }),
|
|
58321
|
-
" First / last item"
|
|
58322
|
-
] }),
|
|
58323
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { children: [
|
|
58324
|
-
" ",
|
|
58325
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { bold: true, children: "Enter" }),
|
|
58326
|
-
" Focus detail pane"
|
|
58327
|
-
] }),
|
|
58328
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { children: [
|
|
58329
|
-
" ",
|
|
58330
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { bold: true, children: "h / \u2190" }),
|
|
58331
|
-
" Return to side"
|
|
58332
|
-
] }),
|
|
58333
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { children: [
|
|
58334
|
-
" ",
|
|
58335
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { bold: true, children: "[ / ]" }),
|
|
58336
|
-
" Cycle detail tabs"
|
|
58337
|
-
] }),
|
|
58338
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { children: [
|
|
58339
|
-
" ",
|
|
58340
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { bold: true, children: "z" }),
|
|
58341
|
-
" Cycle layout mode"
|
|
58342
|
-
] }),
|
|
58450
|
+
helpRow("Tab", "Toggle side / detail focus"),
|
|
58451
|
+
helpRow("j / \u2193", "Next item / scroll down"),
|
|
58452
|
+
helpRow("k / \u2191", "Prev item / scroll up"),
|
|
58453
|
+
helpRow("g / G", "First / last item"),
|
|
58454
|
+
helpRow("Enter", "Focus detail pane"),
|
|
58455
|
+
helpRow("h / \u2190", "Return to side"),
|
|
58456
|
+
helpRow("[ / ]", "Cycle detail tabs"),
|
|
58457
|
+
helpRow("z", "Cycle layout mode"),
|
|
58343
58458
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { children: " " }),
|
|
58344
58459
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { bold: true, children: " Actions" }),
|
|
58345
|
-
|
|
58346
|
-
|
|
58347
|
-
|
|
58348
|
-
" Context menu"
|
|
58349
|
-
] }),
|
|
58350
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { children: [
|
|
58351
|
-
" ",
|
|
58352
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { bold: true, children: "/" }),
|
|
58353
|
-
" Filter side list"
|
|
58354
|
-
] }),
|
|
58355
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { children: [
|
|
58356
|
-
" ",
|
|
58357
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { bold: true, children: "f" }),
|
|
58358
|
-
" Toggle session filter"
|
|
58359
|
-
] }),
|
|
58460
|
+
helpRow("x", "Context menu"),
|
|
58461
|
+
helpRow("/", "Filter side list"),
|
|
58462
|
+
helpRow("f", "Toggle session filter"),
|
|
58360
58463
|
(actions.length > 0 || bindings.length > 0) && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
58361
58464
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { children: " " }),
|
|
58362
58465
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { bold: true, children: [
|
|
@@ -58364,55 +58467,28 @@ function HelpOverlay({ panels, activePanelIndex }) {
|
|
|
58364
58467
|
panel.title,
|
|
58365
58468
|
" Actions"
|
|
58366
58469
|
] }),
|
|
58367
|
-
actions.map((a) => /* @__PURE__ */ (0, import_jsx_runtime9.
|
|
58368
|
-
|
|
58369
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { bold: true, children: a.key }),
|
|
58370
|
-
" ",
|
|
58371
|
-
a.label
|
|
58372
|
-
] }, a.key)),
|
|
58373
|
-
bindings.map((b) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { children: [
|
|
58374
|
-
" ",
|
|
58375
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { bold: true, children: b.keys.join("/") }),
|
|
58376
|
-
" ",
|
|
58377
|
-
b.label
|
|
58378
|
-
] }, b.keys[0]))
|
|
58470
|
+
actions.map((a) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react33.default.Fragment, { children: helpRow(a.key, a.label) }, a.key)),
|
|
58471
|
+
bindings.map((b) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react33.default.Fragment, { children: helpRow(b.keys.join("/"), b.label) }, b.keys[0]))
|
|
58379
58472
|
] }),
|
|
58380
58473
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { children: " " }),
|
|
58381
58474
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { bold: true, children: " General" }),
|
|
58382
|
-
|
|
58383
|
-
|
|
58384
|
-
|
|
58385
|
-
|
|
58386
|
-
|
|
58387
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { children: [
|
|
58388
|
-
" ",
|
|
58389
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { bold: true, children: "V" }),
|
|
58390
|
-
" Version & changelog"
|
|
58391
|
-
] }),
|
|
58392
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { children: [
|
|
58393
|
-
" ",
|
|
58394
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { bold: true, children: "?" }),
|
|
58395
|
-
" Toggle this help"
|
|
58396
|
-
] }),
|
|
58397
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { children: [
|
|
58398
|
-
" ",
|
|
58399
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { bold: true, children: "Esc" }),
|
|
58400
|
-
" Close overlay / clear filter / back"
|
|
58401
|
-
] }),
|
|
58402
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { children: [
|
|
58403
|
-
" ",
|
|
58404
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { bold: true, children: "q / Ctrl+C" }),
|
|
58405
|
-
" Quit"
|
|
58406
|
-
] })
|
|
58475
|
+
helpRow("r", "Generate HTML report"),
|
|
58476
|
+
helpRow("V", "Version & changelog"),
|
|
58477
|
+
helpRow("?", "Toggle this help"),
|
|
58478
|
+
helpRow("Esc", "Close overlay / clear filter"),
|
|
58479
|
+
helpRow("q / Ctrl+C", "Quit")
|
|
58407
58480
|
]
|
|
58408
58481
|
}
|
|
58409
58482
|
) });
|
|
58410
58483
|
}
|
|
58411
|
-
var import_jsx_runtime9;
|
|
58484
|
+
var import_react33, import_jsx_runtime9;
|
|
58412
58485
|
var init_HelpOverlay = __esm({
|
|
58413
58486
|
async "src/dashboard/ink/HelpOverlay.tsx"() {
|
|
58414
58487
|
"use strict";
|
|
58488
|
+
import_react33 = __toESM(require_react(), 1);
|
|
58415
58489
|
await init_build2();
|
|
58490
|
+
init_branding();
|
|
58491
|
+
await init_parseBlessedTags();
|
|
58416
58492
|
import_jsx_runtime9 = __toESM(require_jsx_runtime(), 1);
|
|
58417
58493
|
}
|
|
58418
58494
|
});
|
|
@@ -58497,7 +58573,7 @@ function ChangelogOverlay({ entries, scrollOffset }) {
|
|
|
58497
58573
|
" ",
|
|
58498
58574
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Text, { bold: true, color: "cyan", children: [
|
|
58499
58575
|
"Terminal Dashboard v",
|
|
58500
|
-
"0.12.
|
|
58576
|
+
"0.12.8"
|
|
58501
58577
|
] }),
|
|
58502
58578
|
latestDate ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Text, { color: "gray", children: [
|
|
58503
58579
|
" \u2014 ",
|
|
@@ -58678,20 +58754,26 @@ var init_TooSmallOverlay = __esm({
|
|
|
58678
58754
|
// src/dashboard/ink/ToastNotification.tsx
|
|
58679
58755
|
function ToastNotification({ toast }) {
|
|
58680
58756
|
const color = SEVERITY_COLOR[toast.severity] || "cyan";
|
|
58757
|
+
const icon = SEVERITY_ICON[toast.severity] || "\u25CF";
|
|
58681
58758
|
const truncMsg = toast.message.length > 56 ? toast.message.substring(0, 53) + "..." : toast.message;
|
|
58682
58759
|
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
58683
58760
|
Box_default,
|
|
58684
58761
|
{
|
|
58685
58762
|
position: "absolute",
|
|
58686
|
-
marginLeft: Math.max(0, process.stdout.columns - truncMsg.length -
|
|
58763
|
+
marginLeft: Math.max(0, process.stdout.columns - truncMsg.length - 8),
|
|
58687
58764
|
marginTop: 0,
|
|
58688
58765
|
borderStyle: "single",
|
|
58689
58766
|
borderColor: color,
|
|
58690
|
-
|
|
58767
|
+
paddingX: 1,
|
|
58768
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(Text, { color, children: [
|
|
58769
|
+
icon,
|
|
58770
|
+
" ",
|
|
58771
|
+
truncMsg
|
|
58772
|
+
] })
|
|
58691
58773
|
}
|
|
58692
58774
|
);
|
|
58693
58775
|
}
|
|
58694
|
-
var import_jsx_runtime14, SEVERITY_COLOR;
|
|
58776
|
+
var import_jsx_runtime14, SEVERITY_COLOR, SEVERITY_ICON;
|
|
58695
58777
|
var init_ToastNotification = __esm({
|
|
58696
58778
|
async "src/dashboard/ink/ToastNotification.tsx"() {
|
|
58697
58779
|
"use strict";
|
|
@@ -58702,6 +58784,14 @@ var init_ToastNotification = __esm({
|
|
|
58702
58784
|
warning: "yellow",
|
|
58703
58785
|
info: "cyan"
|
|
58704
58786
|
};
|
|
58787
|
+
SEVERITY_ICON = {
|
|
58788
|
+
error: "\u2718",
|
|
58789
|
+
// ✘
|
|
58790
|
+
warning: "\u26A0",
|
|
58791
|
+
// ⚠
|
|
58792
|
+
info: "\u25CF"
|
|
58793
|
+
// ●
|
|
58794
|
+
};
|
|
58705
58795
|
}
|
|
58706
58796
|
});
|
|
58707
58797
|
|
|
@@ -58790,7 +58880,7 @@ function InputSink() {
|
|
|
58790
58880
|
return null;
|
|
58791
58881
|
}
|
|
58792
58882
|
function MouseProvider({ onMouse, children }) {
|
|
58793
|
-
(0,
|
|
58883
|
+
(0, import_react34.useEffect)(() => {
|
|
58794
58884
|
enableMouse();
|
|
58795
58885
|
const handler = (data) => {
|
|
58796
58886
|
const event = parseMouseEvent(data);
|
|
@@ -58812,11 +58902,11 @@ function MouseProvider({ onMouse, children }) {
|
|
|
58812
58902
|
children
|
|
58813
58903
|
] });
|
|
58814
58904
|
}
|
|
58815
|
-
var
|
|
58905
|
+
var import_react34, import_jsx_runtime15;
|
|
58816
58906
|
var init_MouseProvider = __esm({
|
|
58817
58907
|
async "src/dashboard/ink/mouse/MouseProvider.tsx"() {
|
|
58818
58908
|
"use strict";
|
|
58819
|
-
|
|
58909
|
+
import_react34 = __toESM(require_react(), 1);
|
|
58820
58910
|
await init_build2();
|
|
58821
58911
|
init_mouseProtocol();
|
|
58822
58912
|
init_parseMouseEvent();
|
|
@@ -58838,7 +58928,7 @@ var init_mouse = __esm({
|
|
|
58838
58928
|
var CHANGELOG_default;
|
|
58839
58929
|
var init_CHANGELOG = __esm({
|
|
58840
58930
|
"CHANGELOG.md"() {
|
|
58841
|
-
CHANGELOG_default = '# Changelog\n\nAll notable changes to the Sidekick Agent Hub CLI will be documented in this file.\n\nThe format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),\nand this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n\n## [0.12.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';
|
|
58931
|
+
CHANGELOG_default = '# Changelog\n\nAll notable changes to the Sidekick Agent Hub CLI will be documented in this file.\n\nThe format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),\nand this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n\n## [0.12.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';
|
|
58842
58932
|
}
|
|
58843
58933
|
});
|
|
58844
58934
|
|
|
@@ -58931,20 +59021,20 @@ function reducer(state, action) {
|
|
|
58931
59021
|
}
|
|
58932
59022
|
}
|
|
58933
59023
|
function Dashboard({ panels, metrics, staticData, isPinned, pendingSessionPath, onSessionSwitch, onTogglePin, onGenerateReport }) {
|
|
58934
|
-
const [state, dispatch] = (0,
|
|
59024
|
+
const [state, dispatch] = (0, import_react35.useReducer)(reducer, initialState);
|
|
58935
59025
|
const { exit } = use_app_default();
|
|
58936
59026
|
const { columns, rows } = useTerminalSize();
|
|
58937
|
-
const toastIdRef = (0,
|
|
58938
|
-
const lastAlertCountRef = (0,
|
|
58939
|
-
const alertsInitRef = (0,
|
|
58940
|
-
const prevDetailLineCountRef = (0,
|
|
58941
|
-
(0,
|
|
59027
|
+
const toastIdRef = (0, import_react35.useRef)(0);
|
|
59028
|
+
const lastAlertCountRef = (0, import_react35.useRef)(0);
|
|
59029
|
+
const alertsInitRef = (0, import_react35.useRef)(false);
|
|
59030
|
+
const prevDetailLineCountRef = (0, import_react35.useRef)(0);
|
|
59031
|
+
(0, import_react35.useEffect)(() => {
|
|
58942
59032
|
if (!state.hasReceivedEvents && metrics.eventCount > 0) {
|
|
58943
59033
|
const prefix = (metrics.sessionStartTime || "").substring(0, 8);
|
|
58944
59034
|
dispatch({ type: "FIRST_EVENT", sessionPrefix: prefix });
|
|
58945
59035
|
}
|
|
58946
59036
|
}, [metrics.eventCount, state.hasReceivedEvents, metrics.sessionStartTime]);
|
|
58947
|
-
(0,
|
|
59037
|
+
(0, import_react35.useEffect)(() => {
|
|
58948
59038
|
if (!alertsInitRef.current) {
|
|
58949
59039
|
lastAlertCountRef.current = metrics.eventCount;
|
|
58950
59040
|
alertsInitRef.current = true;
|
|
@@ -58963,7 +59053,7 @@ function Dashboard({ panels, metrics, staticData, isPinned, pendingSessionPath,
|
|
|
58963
59053
|
}
|
|
58964
59054
|
lastAlertCountRef.current = metrics.eventCount;
|
|
58965
59055
|
}, [metrics.eventCount, metrics.timeline]);
|
|
58966
|
-
const addToast = (0,
|
|
59056
|
+
const addToast = (0, import_react35.useCallback)((message, severity) => {
|
|
58967
59057
|
const durations = { error: 4e3, warning: 3e3, info: 2e3 };
|
|
58968
59058
|
const id = ++toastIdRef.current;
|
|
58969
59059
|
dispatch({
|
|
@@ -58987,7 +59077,7 @@ function Dashboard({ panels, metrics, staticData, isPinned, pendingSessionPath,
|
|
|
58987
59077
|
}
|
|
58988
59078
|
};
|
|
58989
59079
|
const sideWidth = getSideWidth();
|
|
58990
|
-
const getFilteredItems = (0,
|
|
59080
|
+
const getFilteredItems = (0, import_react35.useCallback)(() => {
|
|
58991
59081
|
let items = panel.getItems(metrics, staticData);
|
|
58992
59082
|
if (state.sessionFilter && ["tasks", "kanban", "notes", "decisions", "plans"].includes(panel.id)) {
|
|
58993
59083
|
if (panel.id === "kanban") {
|
|
@@ -59016,7 +59106,7 @@ function Dashboard({ panels, metrics, staticData, isPinned, pendingSessionPath,
|
|
|
59016
59106
|
totalItems: currentItems.length,
|
|
59017
59107
|
viewportHeight: sideViewportHeight
|
|
59018
59108
|
});
|
|
59019
|
-
(0,
|
|
59109
|
+
(0, import_react35.useEffect)(() => {
|
|
59020
59110
|
if (sideScroll.selectedIndex !== state.selectedItemIndex) {
|
|
59021
59111
|
sideScroll.setSelected(state.selectedItemIndex);
|
|
59022
59112
|
}
|
|
@@ -59038,7 +59128,7 @@ function Dashboard({ panels, metrics, staticData, isPinned, pendingSessionPath,
|
|
|
59038
59128
|
const detailLines = detailContent.split("\n");
|
|
59039
59129
|
const detailViewportHeight = Math.max(1, rows - 5);
|
|
59040
59130
|
const activeTab = detailTabs[tabIdx];
|
|
59041
|
-
(0,
|
|
59131
|
+
(0, import_react35.useEffect)(() => {
|
|
59042
59132
|
if (!activeTab?.autoScrollBottom) return;
|
|
59043
59133
|
if (detailLines.length <= detailViewportHeight) return;
|
|
59044
59134
|
if (detailLines.length > prevDetailLineCountRef.current) {
|
|
@@ -59050,12 +59140,12 @@ function Dashboard({ panels, metrics, staticData, isPinned, pendingSessionPath,
|
|
|
59050
59140
|
if ("activeDetailTabIndex" in panel) {
|
|
59051
59141
|
panel.activeDetailTabIndex = state.detailTabIndex;
|
|
59052
59142
|
}
|
|
59053
|
-
const getContextActions = (0,
|
|
59143
|
+
const getContextActions = (0, import_react35.useCallback)(() => {
|
|
59054
59144
|
if (!selectedItem) return [];
|
|
59055
59145
|
return panel.getActions().filter((a) => !a.condition || a.condition(selectedItem));
|
|
59056
59146
|
}, [panel, selectedItem]);
|
|
59057
59147
|
const contextActions = state.overlay === "context-menu" ? getContextActions() : [];
|
|
59058
|
-
const buildPanelHints = (0,
|
|
59148
|
+
const buildPanelHints = (0, import_react35.useCallback)(() => {
|
|
59059
59149
|
const parts = [];
|
|
59060
59150
|
const bindings = panel.getKeybindings?.() || [];
|
|
59061
59151
|
for (const b of bindings) {
|
|
@@ -59071,7 +59161,7 @@ function Dashboard({ panels, metrics, staticData, isPinned, pendingSessionPath,
|
|
|
59071
59161
|
}
|
|
59072
59162
|
return parts.length > 0 ? parts.join(" ") + " " : "";
|
|
59073
59163
|
}, [panel, selectedItem, state.focusTarget]);
|
|
59074
|
-
const toggleSessionFilter = (0,
|
|
59164
|
+
const toggleSessionFilter = (0, import_react35.useCallback)(() => {
|
|
59075
59165
|
if (state.sessionFilter) {
|
|
59076
59166
|
dispatch({ type: "SET_SESSION_FILTER", filter: null });
|
|
59077
59167
|
addToast("Session filter cleared", "info");
|
|
@@ -59109,7 +59199,7 @@ function Dashboard({ panels, metrics, staticData, isPinned, pendingSessionPath,
|
|
|
59109
59199
|
addToast("Cannot filter by this item", "info");
|
|
59110
59200
|
}
|
|
59111
59201
|
}, [state.sessionFilter, state.activePanelIndex, selectedItem, panels, metrics, staticData, addToast]);
|
|
59112
|
-
const handleMouse = (0,
|
|
59202
|
+
const handleMouse = (0, import_react35.useCallback)((event) => {
|
|
59113
59203
|
if (state.overlay) {
|
|
59114
59204
|
if (event.type === "click") {
|
|
59115
59205
|
dispatch({ type: "SET_OVERLAY", overlay: null });
|
|
@@ -59422,7 +59512,8 @@ function Dashboard({ panels, metrics, staticData, isPinned, pendingSessionPath,
|
|
|
59422
59512
|
width: sideWidth,
|
|
59423
59513
|
viewportHeight: sideViewportHeight,
|
|
59424
59514
|
panelTitle: panel.title,
|
|
59425
|
-
sessionFilterActive: !!state.sessionFilter && ["tasks", "kanban", "notes", "decisions", "plans"].includes(panel.id)
|
|
59515
|
+
sessionFilterActive: !!state.sessionFilter && ["tasks", "kanban", "notes", "decisions", "plans"].includes(panel.id),
|
|
59516
|
+
emptyStateHint: panel.emptyStateHint
|
|
59426
59517
|
}
|
|
59427
59518
|
),
|
|
59428
59519
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Box_default, { flexDirection: "column", flexGrow: 1, children: [
|
|
@@ -59513,11 +59604,11 @@ function filterKanbanColumn(item, filter) {
|
|
|
59513
59604
|
data: { status: colData.status, tasks: filtered }
|
|
59514
59605
|
};
|
|
59515
59606
|
}
|
|
59516
|
-
var
|
|
59607
|
+
var import_react35, import_sidekick_shared9, import_jsx_runtime16, changelogEntries, SIDE_PANEL_WIDTH, NARROW_SIDE_WIDTH, MIN_SCREEN_WIDTH, MIN_SCREEN_HEIGHT, WIDE_SIDE_WIDTH, initialState;
|
|
59517
59608
|
var init_Dashboard = __esm({
|
|
59518
59609
|
async "src/dashboard/ink/Dashboard.tsx"() {
|
|
59519
59610
|
"use strict";
|
|
59520
|
-
|
|
59611
|
+
import_react35 = __toESM(require_react(), 1);
|
|
59521
59612
|
await init_build2();
|
|
59522
59613
|
init_phraseFormatters();
|
|
59523
59614
|
init_useTerminalSize();
|
|
@@ -59770,7 +59861,7 @@ async function dashboardAction(_opts, cmd) {
|
|
|
59770
59861
|
(0, import_sidekick_shared10.openInBrowser)(outFile);
|
|
59771
59862
|
};
|
|
59772
59863
|
const instance = render2(
|
|
59773
|
-
|
|
59864
|
+
import_react36.default.createElement(Dashboard, {
|
|
59774
59865
|
panels,
|
|
59775
59866
|
metrics: state.getMetrics(),
|
|
59776
59867
|
staticData,
|
|
@@ -59790,7 +59881,7 @@ async function dashboardAction(_opts, cmd) {
|
|
|
59790
59881
|
renderTimer = setTimeout(() => {
|
|
59791
59882
|
renderTimer = null;
|
|
59792
59883
|
instance.rerender(
|
|
59793
|
-
|
|
59884
|
+
import_react36.default.createElement(Dashboard, {
|
|
59794
59885
|
panels,
|
|
59795
59886
|
metrics: state.getMetrics(),
|
|
59796
59887
|
staticData,
|
|
@@ -59918,11 +60009,11 @@ async function dashboardAction(_opts, cmd) {
|
|
|
59918
60009
|
cleanup();
|
|
59919
60010
|
process.exit(0);
|
|
59920
60011
|
}
|
|
59921
|
-
var
|
|
60012
|
+
var import_react36, import_sidekick_shared10, import_sidekick_shared11;
|
|
59922
60013
|
var init_dashboard = __esm({
|
|
59923
60014
|
async "src/commands/dashboard.ts"() {
|
|
59924
60015
|
"use strict";
|
|
59925
|
-
|
|
60016
|
+
import_react36 = __toESM(require_react(), 1);
|
|
59926
60017
|
import_sidekick_shared10 = __toESM(require_dist(), 1);
|
|
59927
60018
|
import_sidekick_shared11 = __toESM(require_dist(), 1);
|
|
59928
60019
|
init_cli();
|
|
@@ -60103,7 +60194,7 @@ var init_cli = __esm({
|
|
|
60103
60194
|
import_sidekick_shared14 = __toESM(require_dist(), 1);
|
|
60104
60195
|
import_sidekick_shared15 = __toESM(require_dist(), 1);
|
|
60105
60196
|
program2 = new Command();
|
|
60106
|
-
program2.name("sidekick").description("Query Sidekick project intelligence from the command line").version("0.12.
|
|
60197
|
+
program2.name("sidekick").description("Query Sidekick project intelligence from the command line").version("0.12.8").option("--json", "Output as JSON").option("--project <path>", "Override project path (default: cwd)").option("--provider <id>", "Provider: claude-code, opencode, codex, auto (default: auto)");
|
|
60107
60198
|
dashCmd = new Command("dashboard").description("Full-screen TUI dashboard with live session metrics").option("--session <id>", "Follow a specific session (default: most recent)").option("--replay", "Replay existing events before streaming new ones").action(async (_opts, cmd) => {
|
|
60108
60199
|
const { dashboardAction: dashboardAction2 } = await init_dashboard().then(() => dashboard_exports);
|
|
60109
60200
|
return dashboardAction2(_opts, cmd);
|