sidekick-docker 0.2.1 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -0
- package/dist/sidekick-docker.mjs +520 -214
- package/package.json +1 -1
package/dist/sidekick-docker.mjs
CHANGED
|
@@ -56086,7 +56086,7 @@ var require_ComposeClient = __commonJS({
|
|
|
56086
56086
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
56087
56087
|
exports2.ComposeClient = void 0;
|
|
56088
56088
|
var child_process_1 = __require("child_process");
|
|
56089
|
-
var
|
|
56089
|
+
var ComposeClient3 = class {
|
|
56090
56090
|
async exec(args, cwd2) {
|
|
56091
56091
|
return new Promise((resolve, reject) => {
|
|
56092
56092
|
const proc = (0, child_process_1.spawn)("docker", ["compose", ...args], {
|
|
@@ -56224,7 +56224,7 @@ var require_ComposeClient = __commonJS({
|
|
|
56224
56224
|
}
|
|
56225
56225
|
}
|
|
56226
56226
|
};
|
|
56227
|
-
exports2.ComposeClient =
|
|
56227
|
+
exports2.ComposeClient = ComposeClient3;
|
|
56228
56228
|
}
|
|
56229
56229
|
});
|
|
56230
56230
|
|
|
@@ -56511,7 +56511,7 @@ var require_LogFilter = __commonJS({
|
|
|
56511
56511
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
56512
56512
|
exports2.exactMatch = exactMatch;
|
|
56513
56513
|
exports2.fuzzyMatch = fuzzyMatch;
|
|
56514
|
-
exports2.filterLine =
|
|
56514
|
+
exports2.filterLine = filterLine4;
|
|
56515
56515
|
function exactMatch(line, query) {
|
|
56516
56516
|
if (!query)
|
|
56517
56517
|
return { matched: true, matches: [] };
|
|
@@ -56546,7 +56546,7 @@ var require_LogFilter = __commonJS({
|
|
|
56546
56546
|
matches.sort((a, b) => a.start - b.start);
|
|
56547
56547
|
return { matched: true, matches };
|
|
56548
56548
|
}
|
|
56549
|
-
function
|
|
56549
|
+
function filterLine4(line, query, mode) {
|
|
56550
56550
|
return mode === "exact" ? exactMatch(line, query) : fuzzyMatch(line, query);
|
|
56551
56551
|
}
|
|
56552
56552
|
}
|
|
@@ -94249,7 +94249,7 @@ var {
|
|
|
94249
94249
|
|
|
94250
94250
|
// src/commands/dashboard.ts
|
|
94251
94251
|
var import_react37 = __toESM(require_react(), 1);
|
|
94252
|
-
var
|
|
94252
|
+
var import_sidekick_docker_shared14 = __toESM(require_dist(), 1);
|
|
94253
94253
|
import { spawnSync } from "child_process";
|
|
94254
94254
|
|
|
94255
94255
|
// src/utils/clipboard.ts
|
|
@@ -94290,6 +94290,8 @@ var DockerState = class {
|
|
|
94290
94290
|
composeProjects = [];
|
|
94291
94291
|
selectedLogs = [];
|
|
94292
94292
|
selectedComposeLogs = [];
|
|
94293
|
+
secondaryLogs = [];
|
|
94294
|
+
secondaryComposeLogs = [];
|
|
94293
94295
|
inspectedEnv = /* @__PURE__ */ new Map();
|
|
94294
94296
|
containerChanges = /* @__PURE__ */ new Map();
|
|
94295
94297
|
imageLayers = /* @__PURE__ */ new Map();
|
|
@@ -94400,6 +94402,18 @@ var DockerState = class {
|
|
|
94400
94402
|
clearComposeLogs() {
|
|
94401
94403
|
this.selectedComposeLogs = [];
|
|
94402
94404
|
}
|
|
94405
|
+
setSecondaryLogs(logs) {
|
|
94406
|
+
this.secondaryLogs = logs;
|
|
94407
|
+
}
|
|
94408
|
+
clearSecondaryLogs() {
|
|
94409
|
+
this.secondaryLogs = [];
|
|
94410
|
+
}
|
|
94411
|
+
setSecondaryComposeLogs(logs) {
|
|
94412
|
+
this.secondaryComposeLogs = logs;
|
|
94413
|
+
}
|
|
94414
|
+
clearSecondaryComposeLogs() {
|
|
94415
|
+
this.secondaryComposeLogs = [];
|
|
94416
|
+
}
|
|
94403
94417
|
getStatsCollector() {
|
|
94404
94418
|
return this.statsCollector;
|
|
94405
94419
|
}
|
|
@@ -94434,13 +94448,17 @@ var DockerState = class {
|
|
|
94434
94448
|
imageLayers: this.imageLayers,
|
|
94435
94449
|
selectedContainerLogs: [...this.selectedLogs],
|
|
94436
94450
|
selectedComposeLogs: [...this.selectedComposeLogs],
|
|
94451
|
+
secondaryContainerLogs: [...this.secondaryLogs],
|
|
94452
|
+
secondaryComposeLogs: [...this.secondaryComposeLogs],
|
|
94437
94453
|
lastRefresh: this.lastRefresh,
|
|
94438
94454
|
daemonConnected: this.daemonConnected,
|
|
94439
94455
|
logFilterString: "",
|
|
94440
94456
|
logFilterMode: "exact",
|
|
94441
94457
|
logSeverityCounts: null,
|
|
94442
94458
|
logSeverityTimeSeries: [],
|
|
94443
|
-
logTemplates: []
|
|
94459
|
+
logTemplates: [],
|
|
94460
|
+
secondaryLogSeverityCounts: null,
|
|
94461
|
+
secondaryLogSeverityTimeSeries: []
|
|
94444
94462
|
};
|
|
94445
94463
|
}
|
|
94446
94464
|
};
|
|
@@ -94661,6 +94679,64 @@ function colorizeNetworkContainer(name, id) {
|
|
|
94661
94679
|
function stripCursorEscapes(text) {
|
|
94662
94680
|
return text.replace(/\x1b\[\d*[ABCD]/g, "").replace(/\x1b\[\d*(?:;\d*)?[Hf]/g, "").replace(/\x1b\[\d*[JK]/g, "").replace(/\x1b\[\?\d+[hl]/g, "").replace(/\x1b\[[su]/g, "").replace(/\x1b[78]/g, "").replace(/\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)/g, "").replace(/\r/g, "");
|
|
94663
94681
|
}
|
|
94682
|
+
function renderLogLines(logs, filterString, filterMode, severityCounts) {
|
|
94683
|
+
const lines = [];
|
|
94684
|
+
if (severityCounts && severityCounts.total > 0) {
|
|
94685
|
+
const parts = [];
|
|
94686
|
+
if (severityCounts.error > 0) parts.push(`\x1B[31mE:${severityCounts.error}\x1B[39m`);
|
|
94687
|
+
if (severityCounts.warn > 0) parts.push(`\x1B[33mW:${severityCounts.warn}\x1B[39m`);
|
|
94688
|
+
if (severityCounts.info > 0) parts.push(`\x1B[38;2;43;76;126mI:${severityCounts.info}\x1B[39m`);
|
|
94689
|
+
if (severityCounts.debug > 0) parts.push(`\x1B[90mD:${severityCounts.debug}\x1B[39m`);
|
|
94690
|
+
if (parts.length > 0) lines.push(parts.join(" "));
|
|
94691
|
+
}
|
|
94692
|
+
if (filterString) {
|
|
94693
|
+
let matchCount = 0;
|
|
94694
|
+
for (const l of logs) {
|
|
94695
|
+
const result = (0, import_sidekick_docker_shared2.filterLine)(l.message, filterString, filterMode);
|
|
94696
|
+
if (result.matched) {
|
|
94697
|
+
matchCount++;
|
|
94698
|
+
lines.push(colorizeLogEntry(l, result.matches));
|
|
94699
|
+
}
|
|
94700
|
+
}
|
|
94701
|
+
if (lines.length <= (severityCounts ? 1 : 0)) {
|
|
94702
|
+
lines.push(`\x1B[90mNo logs matching "${filterString}"\x1B[39m`);
|
|
94703
|
+
} else {
|
|
94704
|
+
const headerIdx = severityCounts ? 1 : 0;
|
|
94705
|
+
lines.splice(headerIdx, 0, `\x1B[90m${matchCount} matches (f to filter, Tab to toggle mode)\x1B[39m`);
|
|
94706
|
+
}
|
|
94707
|
+
} else {
|
|
94708
|
+
for (const l of logs) {
|
|
94709
|
+
lines.push(colorizeLogEntry(l));
|
|
94710
|
+
}
|
|
94711
|
+
}
|
|
94712
|
+
return lines;
|
|
94713
|
+
}
|
|
94714
|
+
function clipAnsi(str, maxWidth) {
|
|
94715
|
+
let visible = 0;
|
|
94716
|
+
let i = 0;
|
|
94717
|
+
let result = "";
|
|
94718
|
+
while (i < str.length && visible < maxWidth) {
|
|
94719
|
+
if (str[i] === "\x1B") {
|
|
94720
|
+
const start = i;
|
|
94721
|
+
i++;
|
|
94722
|
+
if (i < str.length && str[i] === "[") {
|
|
94723
|
+
i++;
|
|
94724
|
+
while (i < str.length && str[i] !== "m" && !/[A-Za-z]/.test(str[i])) i++;
|
|
94725
|
+
if (i < str.length) i++;
|
|
94726
|
+
}
|
|
94727
|
+
result += str.slice(start, i);
|
|
94728
|
+
} else {
|
|
94729
|
+
result += str[i];
|
|
94730
|
+
visible++;
|
|
94731
|
+
i++;
|
|
94732
|
+
}
|
|
94733
|
+
}
|
|
94734
|
+
if (visible < maxWidth) {
|
|
94735
|
+
result += " ".repeat(maxWidth - visible);
|
|
94736
|
+
}
|
|
94737
|
+
result += "\x1B[0m";
|
|
94738
|
+
return result;
|
|
94739
|
+
}
|
|
94664
94740
|
|
|
94665
94741
|
// src/dashboard/panels/ContainersPanel.ts
|
|
94666
94742
|
var ContainersPanel = class {
|
|
@@ -94687,41 +94763,10 @@ var ContainersPanel = class {
|
|
|
94687
94763
|
detailTabs = [
|
|
94688
94764
|
{
|
|
94689
94765
|
label: "Logs",
|
|
94690
|
-
render: (
|
|
94766
|
+
render: (_item, metrics) => {
|
|
94691
94767
|
const logs = metrics.selectedContainerLogs;
|
|
94692
94768
|
if (logs.length === 0) return "No logs available. Select a container to view logs.";
|
|
94693
|
-
|
|
94694
|
-
if (metrics.logSeverityCounts && metrics.logSeverityCounts.total > 0) {
|
|
94695
|
-
const c = metrics.logSeverityCounts;
|
|
94696
|
-
const parts = [];
|
|
94697
|
-
if (c.error > 0) parts.push(`\x1B[31mE:${c.error}\x1B[39m`);
|
|
94698
|
-
if (c.warn > 0) parts.push(`\x1B[33mW:${c.warn}\x1B[39m`);
|
|
94699
|
-
if (c.info > 0) parts.push(`\x1B[38;2;43;76;126mI:${c.info}\x1B[39m`);
|
|
94700
|
-
if (c.debug > 0) parts.push(`\x1B[90mD:${c.debug}\x1B[39m`);
|
|
94701
|
-
if (parts.length > 0) lines.push(parts.join(" "));
|
|
94702
|
-
}
|
|
94703
|
-
const query = metrics.logFilterString;
|
|
94704
|
-
const mode = metrics.logFilterMode;
|
|
94705
|
-
if (query) {
|
|
94706
|
-
let matchCount = 0;
|
|
94707
|
-
for (const l of logs) {
|
|
94708
|
-
const result = (0, import_sidekick_docker_shared4.filterLine)(l.message, query, mode);
|
|
94709
|
-
if (result.matched) {
|
|
94710
|
-
matchCount++;
|
|
94711
|
-
lines.push(colorizeLogEntry(l, result.matches));
|
|
94712
|
-
}
|
|
94713
|
-
}
|
|
94714
|
-
if (lines.length <= 1) {
|
|
94715
|
-
lines.push(`\x1B[90mNo logs matching "${query}"\x1B[39m`);
|
|
94716
|
-
} else {
|
|
94717
|
-
lines.splice(1, 0, `\x1B[90m${matchCount} matches (f to filter, Tab to toggle mode)\x1B[39m`);
|
|
94718
|
-
}
|
|
94719
|
-
} else {
|
|
94720
|
-
for (const l of logs) {
|
|
94721
|
-
lines.push(colorizeLogEntry(l));
|
|
94722
|
-
}
|
|
94723
|
-
}
|
|
94724
|
-
return lines.join("\n");
|
|
94769
|
+
return renderLogLines(logs, metrics.logFilterString, metrics.logFilterMode, metrics.logSeverityCounts).join("\n");
|
|
94725
94770
|
},
|
|
94726
94771
|
autoScrollBottom: true
|
|
94727
94772
|
},
|
|
@@ -94965,6 +95010,7 @@ var ContainersPanel = class {
|
|
|
94965
95010
|
};
|
|
94966
95011
|
|
|
94967
95012
|
// src/dashboard/panels/ServicesPanel.ts
|
|
95013
|
+
var import_sidekick_docker_shared5 = __toESM(require_dist(), 1);
|
|
94968
95014
|
function getProjectName(d) {
|
|
94969
95015
|
return d.type === "project" ? d.project.name : d.service.projectName;
|
|
94970
95016
|
}
|
|
@@ -94976,12 +95022,17 @@ var ServicesPanel = class {
|
|
|
94976
95022
|
onAction;
|
|
94977
95023
|
onError;
|
|
94978
95024
|
cwd;
|
|
95025
|
+
onCopyLogs;
|
|
95026
|
+
lastMetrics = null;
|
|
94979
95027
|
constructor(composeClient, onAction, cwd2, onError) {
|
|
94980
95028
|
this.composeClient = composeClient;
|
|
94981
95029
|
this.onAction = onAction;
|
|
94982
95030
|
this.onError = onError ?? defaultOnError;
|
|
94983
95031
|
this.cwd = cwd2;
|
|
94984
95032
|
}
|
|
95033
|
+
setOnCopyLogs(handler) {
|
|
95034
|
+
this.onCopyLogs = handler;
|
|
95035
|
+
}
|
|
94985
95036
|
detailTabs = [
|
|
94986
95037
|
{
|
|
94987
95038
|
label: "Info",
|
|
@@ -95015,12 +95066,13 @@ var ServicesPanel = class {
|
|
|
95015
95066
|
render: (_item, metrics) => {
|
|
95016
95067
|
const logs = metrics.selectedComposeLogs;
|
|
95017
95068
|
if (logs.length === 0) return "No compose logs. Logs will appear when a service produces output.";
|
|
95018
|
-
return logs.
|
|
95069
|
+
return renderLogLines(logs, metrics.logFilterString, metrics.logFilterMode).join("\n");
|
|
95019
95070
|
},
|
|
95020
95071
|
autoScrollBottom: true
|
|
95021
95072
|
}
|
|
95022
95073
|
];
|
|
95023
95074
|
getItems(metrics) {
|
|
95075
|
+
this.lastMetrics = metrics;
|
|
95024
95076
|
const items = [];
|
|
95025
95077
|
let sortKey = 0;
|
|
95026
95078
|
for (const project of metrics.composeProjects) {
|
|
@@ -95115,6 +95167,23 @@ var ServicesPanel = class {
|
|
|
95115
95167
|
});
|
|
95116
95168
|
},
|
|
95117
95169
|
condition: (item) => item.data !== null
|
|
95170
|
+
},
|
|
95171
|
+
{
|
|
95172
|
+
key: "c",
|
|
95173
|
+
label: "Copy Logs",
|
|
95174
|
+
handler: () => {
|
|
95175
|
+
if (!this.lastMetrics || !this.onCopyLogs) return;
|
|
95176
|
+
const logs = this.lastMetrics.selectedComposeLogs;
|
|
95177
|
+
const query = this.lastMetrics.logFilterString;
|
|
95178
|
+
const mode = this.lastMetrics.logFilterMode;
|
|
95179
|
+
let lines;
|
|
95180
|
+
if (query) {
|
|
95181
|
+
lines = logs.filter((l) => (0, import_sidekick_docker_shared5.filterLine)(l.message, query, mode).matched).map((l) => l.message);
|
|
95182
|
+
} else {
|
|
95183
|
+
lines = logs.map((l) => l.message);
|
|
95184
|
+
}
|
|
95185
|
+
this.onCopyLogs(lines.join("\n"));
|
|
95186
|
+
}
|
|
95118
95187
|
}
|
|
95119
95188
|
];
|
|
95120
95189
|
}
|
|
@@ -95400,15 +95469,15 @@ var NetworksPanel = class {
|
|
|
95400
95469
|
};
|
|
95401
95470
|
|
|
95402
95471
|
// src/dashboard/LogStreamManager.ts
|
|
95403
|
-
var
|
|
95472
|
+
var import_sidekick_docker_shared7 = __toESM(require_dist(), 1);
|
|
95404
95473
|
|
|
95405
95474
|
// src/dashboard/BaseStreamManager.ts
|
|
95406
|
-
var
|
|
95475
|
+
var import_sidekick_docker_shared6 = __toESM(require_dist(), 1);
|
|
95407
95476
|
var BaseStreamManager = class {
|
|
95408
95477
|
currentId;
|
|
95409
95478
|
aborted = false;
|
|
95410
95479
|
streamPromise = null;
|
|
95411
|
-
reconnect = new
|
|
95480
|
+
reconnect = new import_sidekick_docker_shared6.ReconnectScheduler();
|
|
95412
95481
|
onChange;
|
|
95413
95482
|
constructor(onChange) {
|
|
95414
95483
|
this.onChange = onChange;
|
|
@@ -95435,7 +95504,7 @@ var BaseStreamManager = class {
|
|
|
95435
95504
|
}
|
|
95436
95505
|
this.reconnect.reset();
|
|
95437
95506
|
} catch (err) {
|
|
95438
|
-
console.debug(`${this.streamLabel} stream error:`, (0,
|
|
95507
|
+
console.debug(`${this.streamLabel} stream error:`, (0, import_sidekick_docker_shared6.errorMessage)(err));
|
|
95439
95508
|
}
|
|
95440
95509
|
if (!this.aborted && this.isSameId(id, this.currentId)) {
|
|
95441
95510
|
const scheduled = this.reconnect.schedule(() => {
|
|
@@ -95472,9 +95541,9 @@ var BaseStreamManager = class {
|
|
|
95472
95541
|
var LogStreamManager = class extends BaseStreamManager {
|
|
95473
95542
|
client;
|
|
95474
95543
|
logs = [];
|
|
95475
|
-
analytics = new
|
|
95476
|
-
timeSeries = new
|
|
95477
|
-
templateEngine = new
|
|
95544
|
+
analytics = new import_sidekick_docker_shared7.LogAnalytics();
|
|
95545
|
+
timeSeries = new import_sidekick_docker_shared7.LogSeverityTimeSeries();
|
|
95546
|
+
templateEngine = new import_sidekick_docker_shared7.LogTemplateEngine();
|
|
95478
95547
|
streamLabel = "log";
|
|
95479
95548
|
constructor(client, onChange) {
|
|
95480
95549
|
super(onChange);
|
|
@@ -95500,7 +95569,7 @@ var LogStreamManager = class extends BaseStreamManager {
|
|
|
95500
95569
|
const severity = this.analytics.push(entry.message);
|
|
95501
95570
|
this.timeSeries.push(severity);
|
|
95502
95571
|
this.templateEngine.push(entry.message);
|
|
95503
|
-
if (this.logs.length >
|
|
95572
|
+
if (this.logs.length > import_sidekick_docker_shared7.MAX_LOG_LINES) {
|
|
95504
95573
|
this.logs.shift();
|
|
95505
95574
|
}
|
|
95506
95575
|
}
|
|
@@ -95569,7 +95638,7 @@ var StatsStreamManager = class extends BaseStreamManager {
|
|
|
95569
95638
|
};
|
|
95570
95639
|
|
|
95571
95640
|
// src/dashboard/ComposeLogStreamManager.ts
|
|
95572
|
-
var
|
|
95641
|
+
var import_sidekick_docker_shared8 = __toESM(require_dist(), 1);
|
|
95573
95642
|
var ComposeLogStreamManager = class extends BaseStreamManager {
|
|
95574
95643
|
composeClient;
|
|
95575
95644
|
logs = [];
|
|
@@ -95595,7 +95664,7 @@ var ComposeLogStreamManager = class extends BaseStreamManager {
|
|
|
95595
95664
|
}
|
|
95596
95665
|
processItem(_id, entry) {
|
|
95597
95666
|
this.logs.push(entry);
|
|
95598
|
-
if (this.logs.length >
|
|
95667
|
+
if (this.logs.length > import_sidekick_docker_shared8.MAX_LOG_LINES) {
|
|
95599
95668
|
this.logs.shift();
|
|
95600
95669
|
}
|
|
95601
95670
|
}
|
|
@@ -95740,7 +95809,7 @@ function handleFilterInput(input, key, opts) {
|
|
|
95740
95809
|
}
|
|
95741
95810
|
function useKeyboardHandler(ctx) {
|
|
95742
95811
|
const { exit } = use_app_default();
|
|
95743
|
-
const { state, dispatch, panels, panel, selectedItem, contextActions, clampedSelection, currentItems, detailLines, detailViewportHeight, detailTabs, tabIdx, panelActions, sideScroll, addToast, removeToast, rotatePhrase } = ctx;
|
|
95812
|
+
const { state, dispatch, panels, panel, selectedItem, contextActions, clampedSelection, currentItems, detailLines, detailViewportHeight, detailTabs, tabIdx, panelActions, sideScroll, addToast, removeToast, rotatePhrase, secondaryDetailLineCount } = ctx;
|
|
95744
95813
|
use_input_default((input, key) => {
|
|
95745
95814
|
if (state.overlay === "exec") return;
|
|
95746
95815
|
rotatePhrase();
|
|
@@ -95911,6 +95980,18 @@ function useKeyboardHandler(ctx) {
|
|
|
95911
95980
|
addToast(`Sort: ${state.sortReversed ? "ascending" : "descending"}`, "info");
|
|
95912
95981
|
return;
|
|
95913
95982
|
}
|
|
95983
|
+
if (input === "m" && selectedItem && (panel.id === "containers" || panel.id === "services")) {
|
|
95984
|
+
const currentCompare = state.compareItemIds[panel.id] ?? null;
|
|
95985
|
+
if (currentCompare === selectedItem.id) {
|
|
95986
|
+
dispatch({ type: "PIN_COMPARE", panelId: panel.id, itemId: selectedItem.id });
|
|
95987
|
+
addToast("Unpinned comparison", "info");
|
|
95988
|
+
} else {
|
|
95989
|
+
dispatch({ type: "PIN_COMPARE", panelId: panel.id, itemId: selectedItem.id });
|
|
95990
|
+
const label = selectedItem.label.replace(/^[^\w]*/, "").trim();
|
|
95991
|
+
addToast(`Pinned ${label} for comparison`, "info");
|
|
95992
|
+
}
|
|
95993
|
+
return;
|
|
95994
|
+
}
|
|
95914
95995
|
if (input === "x") {
|
|
95915
95996
|
if (selectedItem && panelActions.length > 0) {
|
|
95916
95997
|
dispatch({ type: "SET_OVERLAY", overlay: "context-menu" });
|
|
@@ -95956,6 +96037,14 @@ function useKeyboardHandler(ctx) {
|
|
|
95956
96037
|
}
|
|
95957
96038
|
}
|
|
95958
96039
|
if (state.focusTarget === "detail") {
|
|
96040
|
+
if (input === "J" && secondaryDetailLineCount > 0) {
|
|
96041
|
+
dispatch({ type: "SCROLL_SECONDARY_DETAIL_DELTA", delta: 1, totalLines: secondaryDetailLineCount, viewportHeight: detailViewportHeight });
|
|
96042
|
+
return;
|
|
96043
|
+
}
|
|
96044
|
+
if (input === "K" && secondaryDetailLineCount > 0) {
|
|
96045
|
+
dispatch({ type: "SCROLL_SECONDARY_DETAIL_DELTA", delta: -1, totalLines: secondaryDetailLineCount, viewportHeight: detailViewportHeight });
|
|
96046
|
+
return;
|
|
96047
|
+
}
|
|
95959
96048
|
if (input === "j" || key.downArrow) {
|
|
95960
96049
|
dispatch({ type: "SCROLL_DETAIL_DELTA", delta: 1, totalLines: detailLines.length, viewportHeight: detailViewportHeight });
|
|
95961
96050
|
return;
|
|
@@ -96123,7 +96212,7 @@ var EMPTY_HINTS = {
|
|
|
96123
96212
|
networks: ["Create a network to get started:", " docker network create my-net"],
|
|
96124
96213
|
services: ["Start a compose project:", " docker compose up -d"]
|
|
96125
96214
|
};
|
|
96126
|
-
function SideList({ items, selectedIndex, scrollOffset, focused, width, viewportHeight, panelTitle, filterString, panelId, totalCount, runningCount }) {
|
|
96215
|
+
function SideList({ items, selectedIndex, scrollOffset, focused, width, viewportHeight, panelTitle, filterString, panelId, totalCount, runningCount, compareItemId }) {
|
|
96127
96216
|
const hasScrollUp = scrollOffset > 0;
|
|
96128
96217
|
const hasScrollDown = scrollOffset + viewportHeight < items.length;
|
|
96129
96218
|
const aboveCount = scrollOffset;
|
|
@@ -96150,7 +96239,8 @@ function SideList({ items, selectedIndex, scrollOffset, focused, width, viewport
|
|
|
96150
96239
|
const segments = [...trimmed];
|
|
96151
96240
|
const icon = segments[0] || "";
|
|
96152
96241
|
const rest = segments.slice(1).join("");
|
|
96153
|
-
const
|
|
96242
|
+
const isPinned = compareItemId != null && item.id === compareItemId;
|
|
96243
|
+
const rightLabel = isPinned ? `\u{1F4CC}${item.rightLabel ? " " + item.rightLabel : ""}` : item.rightLabel || "";
|
|
96154
96244
|
const rightLen = rightLabel.length;
|
|
96155
96245
|
const leftWidth = innerWidth - rightLen - (rightLen ? 1 : 0);
|
|
96156
96246
|
if (isSelected && focused) {
|
|
@@ -96229,11 +96319,67 @@ function DetailPane({ lines, scrollOffset, viewportHeight, focused }) {
|
|
|
96229
96319
|
] });
|
|
96230
96320
|
}
|
|
96231
96321
|
|
|
96322
|
+
// src/dashboard/ink/CompareDetailPane.tsx
|
|
96323
|
+
await init_build2();
|
|
96324
|
+
var import_jsx_runtime5 = __toESM(require_jsx_runtime(), 1);
|
|
96325
|
+
function CompareDetailPane({
|
|
96326
|
+
primaryLines,
|
|
96327
|
+
secondaryLines,
|
|
96328
|
+
primaryScrollOffset,
|
|
96329
|
+
secondaryScrollOffset,
|
|
96330
|
+
viewportHeight,
|
|
96331
|
+
totalWidth,
|
|
96332
|
+
focused,
|
|
96333
|
+
primaryLabel,
|
|
96334
|
+
secondaryLabel
|
|
96335
|
+
}) {
|
|
96336
|
+
const colWidth = Math.max(10, Math.floor((totalWidth - 5) / 2));
|
|
96337
|
+
const headerLeft = clipAnsi(`\x1B[1m${primaryLabel}\x1B[22m`, colWidth);
|
|
96338
|
+
const headerRight = clipAnsi(`\x1B[1m${secondaryLabel}\x1B[22m`, colWidth);
|
|
96339
|
+
const leftVisible = primaryLines.slice(primaryScrollOffset, primaryScrollOffset + viewportHeight);
|
|
96340
|
+
const rightVisible = secondaryLines.slice(secondaryScrollOffset, secondaryScrollOffset + viewportHeight);
|
|
96341
|
+
const leftHasUp = primaryScrollOffset > 0;
|
|
96342
|
+
const leftHasDown = primaryScrollOffset + viewportHeight < primaryLines.length;
|
|
96343
|
+
const rightHasUp = secondaryScrollOffset > 0;
|
|
96344
|
+
const rightHasDown = secondaryScrollOffset + viewportHeight < secondaryLines.length;
|
|
96345
|
+
const maxRows = Math.max(leftVisible.length, rightVisible.length, viewportHeight);
|
|
96346
|
+
const rows = [];
|
|
96347
|
+
for (let i = 0; i < maxRows && i < viewportHeight; i++) {
|
|
96348
|
+
const left = leftVisible[i] ?? "";
|
|
96349
|
+
const right = rightVisible[i] ?? "";
|
|
96350
|
+
rows.push(
|
|
96351
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
|
|
96352
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { wrap: "truncate", children: clipAnsi(left, colWidth) }),
|
|
96353
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "gray", dimColor: true, children: " \u2502 " }),
|
|
96354
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { wrap: "truncate", children: clipAnsi(right, colWidth) })
|
|
96355
|
+
] }, i)
|
|
96356
|
+
);
|
|
96357
|
+
}
|
|
96358
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { flexDirection: "column", flexGrow: 1, borderStyle: focused ? "bold" : "single", borderColor: focused ? "#2B4C7E" : "gray", children: [
|
|
96359
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
|
|
96360
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { wrap: "truncate", children: headerLeft }),
|
|
96361
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "gray", dimColor: true, children: " \u2502 " }),
|
|
96362
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { wrap: "truncate", children: headerRight })
|
|
96363
|
+
] }),
|
|
96364
|
+
(leftHasUp || rightHasUp) && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
|
|
96365
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "gray", children: leftHasUp ? clipAnsi(`\u25B2 (${primaryScrollOffset} more)`, colWidth) : " ".repeat(colWidth) }),
|
|
96366
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "gray", dimColor: true, children: " \u2502 " }),
|
|
96367
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "gray", children: rightHasUp ? clipAnsi(`\u25B2 (${secondaryScrollOffset} more)`, colWidth) : " ".repeat(colWidth) })
|
|
96368
|
+
] }),
|
|
96369
|
+
rows,
|
|
96370
|
+
(leftHasDown || rightHasDown) && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
|
|
96371
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "gray", children: leftHasDown ? clipAnsi(`\u25BC (${Math.max(0, primaryLines.length - primaryScrollOffset - viewportHeight)} more)`, colWidth) : " ".repeat(colWidth) }),
|
|
96372
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "gray", dimColor: true, children: " \u2502 " }),
|
|
96373
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "gray", children: rightHasDown ? clipAnsi(`\u25BC (${Math.max(0, secondaryLines.length - secondaryScrollOffset - viewportHeight)} more)`, colWidth) : " ".repeat(colWidth) })
|
|
96374
|
+
] })
|
|
96375
|
+
] });
|
|
96376
|
+
}
|
|
96377
|
+
|
|
96232
96378
|
// src/dashboard/ink/StatusBar.tsx
|
|
96233
96379
|
var import_react32 = __toESM(require_react(), 1);
|
|
96234
96380
|
await init_build2();
|
|
96235
|
-
var
|
|
96236
|
-
var
|
|
96381
|
+
var import_sidekick_docker_shared9 = __toESM(require_dist(), 1);
|
|
96382
|
+
var import_jsx_runtime6 = __toESM(require_jsx_runtime(), 1);
|
|
96237
96383
|
function formatAgo(date) {
|
|
96238
96384
|
const secs = Math.floor((Date.now() - date.getTime()) / 1e3);
|
|
96239
96385
|
if (secs < 5) return { text: "just now", stale: false };
|
|
@@ -96249,33 +96395,33 @@ function StatusBar({ daemonConnected, focusTarget, panelActionHints, filterStrin
|
|
|
96249
96395
|
return () => clearInterval(timer);
|
|
96250
96396
|
}, []);
|
|
96251
96397
|
const ago = lastRefresh ? formatAgo(lastRefresh) : null;
|
|
96252
|
-
return /* @__PURE__ */ (0,
|
|
96253
|
-
/* @__PURE__ */ (0,
|
|
96254
|
-
/* @__PURE__ */ (0,
|
|
96255
|
-
/* @__PURE__ */ (0,
|
|
96256
|
-
/* @__PURE__ */ (0,
|
|
96257
|
-
ago && /* @__PURE__ */ (0,
|
|
96258
|
-
/* @__PURE__ */ (0,
|
|
96259
|
-
panelActionHints.length > 0 && /* @__PURE__ */ (0,
|
|
96260
|
-
panelActionHints.map((hint, i) => /* @__PURE__ */ (0,
|
|
96261
|
-
i > 0 && /* @__PURE__ */ (0,
|
|
96262
|
-
/* @__PURE__ */ (0,
|
|
96398
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Box_default, { children: [
|
|
96399
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, color: "magenta", children: ` \u26A1 ${import_sidekick_docker_shared9.BRAND_INLINE}` }),
|
|
96400
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "gray", dimColor: true, children: ` ${import_sidekick_docker_shared9.BRAND_TAGLINE} v${version2}` }),
|
|
96401
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "gray", dimColor: true, children: ` ${SEP2} ` }),
|
|
96402
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: daemonConnected ? "green" : "red", children: daemonConnected ? `\u25CF ${runningCount ?? 0}/${containerCount ?? 0}` : "\u25CB disconnected" }),
|
|
96403
|
+
ago && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: ago.stale ? "yellow" : "gray", dimColor: !ago.stale, children: ` \u21BB ${ago.text}` }),
|
|
96404
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "gray", dimColor: true, children: ` ${SEP2} ` }),
|
|
96405
|
+
panelActionHints.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
96406
|
+
panelActionHints.map((hint, i) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react32.default.Fragment, { children: [
|
|
96407
|
+
i > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
|
|
96408
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: hint.destructive ? "red" : "#2B4C7E", children: `${hint.key}:${hint.label}` })
|
|
96263
96409
|
] }, hint.key)),
|
|
96264
|
-
/* @__PURE__ */ (0,
|
|
96410
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "gray", dimColor: true, children: ` ${SEP2} ` })
|
|
96265
96411
|
] }),
|
|
96266
|
-
/* @__PURE__ */ (0,
|
|
96267
|
-
/* @__PURE__ */ (0,
|
|
96268
|
-
/* @__PURE__ */ (0,
|
|
96269
|
-
/* @__PURE__ */ (0,
|
|
96270
|
-
contextHint ? /* @__PURE__ */ (0,
|
|
96271
|
-
filterString ? /* @__PURE__ */ (0,
|
|
96412
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: focusTarget === "side" ? "#2B4C7E" : "gray", bold: focusTarget === "side", children: "\u25C0" }),
|
|
96413
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "gray", dimColor: true, children: "/" }),
|
|
96414
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: focusTarget === "detail" ? "#2B4C7E" : "gray", bold: focusTarget === "detail", children: "\u25B6" }),
|
|
96415
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "gray", dimColor: true, children: " j/k Tab / ?" }),
|
|
96416
|
+
contextHint ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "cyan", dimColor: true, children: ` ${contextHint}` }) : null,
|
|
96417
|
+
filterString ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "yellow", bold: true, children: ` \u25C9 "${filterString}"${matchCount !== void 0 && totalCount !== void 0 ? ` ${matchCount}/${totalCount}` : ""}` }) : null
|
|
96272
96418
|
] });
|
|
96273
96419
|
}
|
|
96274
96420
|
|
|
96275
96421
|
// src/dashboard/ink/HelpOverlay.tsx
|
|
96276
96422
|
await init_build2();
|
|
96277
|
-
var
|
|
96278
|
-
var
|
|
96423
|
+
var import_sidekick_docker_shared10 = __toESM(require_dist(), 1);
|
|
96424
|
+
var import_jsx_runtime7 = __toESM(require_jsx_runtime(), 1);
|
|
96279
96425
|
var GLOBAL_BINDINGS = [
|
|
96280
96426
|
{ key: "1-5", label: "Switch panel" },
|
|
96281
96427
|
{ key: "j/k", label: "Navigate / scroll" },
|
|
@@ -96288,66 +96434,69 @@ var GLOBAL_BINDINGS = [
|
|
|
96288
96434
|
{ key: "a", label: "Toggle all/running (Containers)" },
|
|
96289
96435
|
{ key: "o", label: "Sort menu (Containers)" },
|
|
96290
96436
|
{ key: "R", label: "Reverse sort (Containers)" },
|
|
96437
|
+
{ key: "f", label: "Log filter (Logs tab)" },
|
|
96438
|
+
{ key: "m", label: "Pin/unpin log comparison" },
|
|
96439
|
+
{ key: "J/K", label: "Scroll compare pane" },
|
|
96291
96440
|
{ key: "V", label: "Version info" },
|
|
96292
96441
|
{ key: "?", label: "This help" },
|
|
96293
96442
|
{ key: "q", label: "Quit" }
|
|
96294
96443
|
];
|
|
96295
96444
|
function KeyBadge({ k }) {
|
|
96296
|
-
return /* @__PURE__ */ (0,
|
|
96445
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: "white", backgroundColor: "#2B4C7E", bold: true, children: ` ${k} ` });
|
|
96297
96446
|
}
|
|
96298
96447
|
function HelpOverlay({ panels, activePanelIndex, version: version2 }) {
|
|
96299
96448
|
const panel = panels[activePanelIndex];
|
|
96300
96449
|
const actions = panel.getActions();
|
|
96301
|
-
return /* @__PURE__ */ (0,
|
|
96302
|
-
/* @__PURE__ */ (0,
|
|
96303
|
-
/* @__PURE__ */ (0,
|
|
96304
|
-
/* @__PURE__ */ (0,
|
|
96450
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Box_default, { flexDirection: "column", flexGrow: 1, padding: 1, children: [
|
|
96451
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Box_default, { children: [
|
|
96452
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, color: "magenta", children: `\u26A1 ${import_sidekick_docker_shared10.BRAND_INLINE} ${import_sidekick_docker_shared10.BRAND_TAGLINE}` }),
|
|
96453
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: "gray", dimColor: true, children: ` v${version2}` })
|
|
96305
96454
|
] }),
|
|
96306
|
-
/* @__PURE__ */ (0,
|
|
96307
|
-
/* @__PURE__ */ (0,
|
|
96308
|
-
/* @__PURE__ */ (0,
|
|
96309
|
-
/* @__PURE__ */ (0,
|
|
96455
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "" }),
|
|
96456
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Box_default, { children: [
|
|
96457
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, color: "yellow", children: "\u2500\u2500 Navigation " }),
|
|
96458
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: "gray", dimColor: true, children: "\u2500".repeat(30) })
|
|
96310
96459
|
] }),
|
|
96311
|
-
/* @__PURE__ */ (0,
|
|
96312
|
-
GLOBAL_BINDINGS.map((b) => /* @__PURE__ */ (0,
|
|
96313
|
-
/* @__PURE__ */ (0,
|
|
96314
|
-
/* @__PURE__ */ (0,
|
|
96460
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "" }),
|
|
96461
|
+
GLOBAL_BINDINGS.map((b) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Box_default, { children: [
|
|
96462
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Box_default, { width: 10, justifyContent: "flex-end", marginRight: 1, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(KeyBadge, { k: b.key }) }),
|
|
96463
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: "gray", children: b.label })
|
|
96315
96464
|
] }, b.key)),
|
|
96316
|
-
actions.length > 0 && /* @__PURE__ */ (0,
|
|
96317
|
-
/* @__PURE__ */ (0,
|
|
96318
|
-
/* @__PURE__ */ (0,
|
|
96319
|
-
/* @__PURE__ */ (0,
|
|
96320
|
-
/* @__PURE__ */ (0,
|
|
96465
|
+
actions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
96466
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "" }),
|
|
96467
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Box_default, { children: [
|
|
96468
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, color: "yellow", children: `\u2500\u2500 ${panel.title} Actions ` }),
|
|
96469
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: "gray", dimColor: true, children: "\u2500".repeat(24) })
|
|
96321
96470
|
] }),
|
|
96322
|
-
/* @__PURE__ */ (0,
|
|
96323
|
-
actions.map((a) => /* @__PURE__ */ (0,
|
|
96324
|
-
/* @__PURE__ */ (0,
|
|
96325
|
-
/* @__PURE__ */ (0,
|
|
96326
|
-
a.confirm && /* @__PURE__ */ (0,
|
|
96471
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "" }),
|
|
96472
|
+
actions.map((a) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Box_default, { children: [
|
|
96473
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Box_default, { width: 10, justifyContent: "flex-end", marginRight: 1, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(KeyBadge, { k: a.key }) }),
|
|
96474
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: a.confirm ? "red" : "gray", children: a.label }),
|
|
96475
|
+
a.confirm && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: "red", dimColor: true, children: " \u26A0" })
|
|
96327
96476
|
] }, a.key))
|
|
96328
96477
|
] }),
|
|
96329
|
-
/* @__PURE__ */ (0,
|
|
96330
|
-
/* @__PURE__ */ (0,
|
|
96478
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "" }),
|
|
96479
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: "gray", dimColor: true, children: "Press ? or Esc to close" })
|
|
96331
96480
|
] });
|
|
96332
96481
|
}
|
|
96333
96482
|
|
|
96334
96483
|
// src/dashboard/ink/FilterOverlay.tsx
|
|
96335
96484
|
await init_build2();
|
|
96336
|
-
var
|
|
96485
|
+
var import_jsx_runtime8 = __toESM(require_jsx_runtime(), 1);
|
|
96337
96486
|
function FilterOverlay({ filterString, matchCount, totalCount, panelTitle }) {
|
|
96338
96487
|
const countInfo = matchCount !== void 0 && totalCount !== void 0 && panelTitle ? ` ${matchCount} of ${totalCount} ${panelTitle.toLowerCase()}` : "";
|
|
96339
|
-
return /* @__PURE__ */ (0,
|
|
96340
|
-
/* @__PURE__ */ (0,
|
|
96341
|
-
countInfo && /* @__PURE__ */ (0,
|
|
96342
|
-
/* @__PURE__ */ (0,
|
|
96488
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Box_default, { position: "absolute", marginTop: 1, marginLeft: 1, children: [
|
|
96489
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { backgroundColor: "#2B4C7E", color: "white", bold: true, children: ` \u2315 ${filterString}\u2588 ` }),
|
|
96490
|
+
countInfo && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { color: "gray", dimColor: true, children: countInfo }),
|
|
96491
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { color: "gray", dimColor: true, children: " Enter: apply Esc: clear" })
|
|
96343
96492
|
] });
|
|
96344
96493
|
}
|
|
96345
96494
|
|
|
96346
96495
|
// src/dashboard/ink/ContextMenuOverlay.tsx
|
|
96347
96496
|
await init_build2();
|
|
96348
|
-
var
|
|
96497
|
+
var import_jsx_runtime9 = __toESM(require_jsx_runtime(), 1);
|
|
96349
96498
|
function ContextMenuOverlay({ actions, selectedIndex }) {
|
|
96350
|
-
return /* @__PURE__ */ (0,
|
|
96499
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
96351
96500
|
Box_default,
|
|
96352
96501
|
{
|
|
96353
96502
|
position: "absolute",
|
|
@@ -96358,13 +96507,13 @@ function ContextMenuOverlay({ actions, selectedIndex }) {
|
|
|
96358
96507
|
borderColor: "#2B4C7E",
|
|
96359
96508
|
paddingX: 1,
|
|
96360
96509
|
children: [
|
|
96361
|
-
/* @__PURE__ */ (0,
|
|
96510
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { bold: true, color: "#2B4C7E", children: "\u2630 Actions" }),
|
|
96362
96511
|
actions.map((action, i) => {
|
|
96363
96512
|
const isSelected = i === selectedIndex;
|
|
96364
96513
|
const isDanger = !!action.confirm;
|
|
96365
96514
|
const color = isSelected ? isDanger ? "red" : "#2B4C7E" : isDanger ? "red" : "white";
|
|
96366
|
-
return /* @__PURE__ */ (0,
|
|
96367
|
-
/* @__PURE__ */ (0,
|
|
96515
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Box_default, { children: [
|
|
96516
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
96368
96517
|
Text,
|
|
96369
96518
|
{
|
|
96370
96519
|
color,
|
|
@@ -96373,7 +96522,7 @@ function ContextMenuOverlay({ actions, selectedIndex }) {
|
|
|
96373
96522
|
children: ` ${action.key} `
|
|
96374
96523
|
}
|
|
96375
96524
|
),
|
|
96376
|
-
/* @__PURE__ */ (0,
|
|
96525
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
96377
96526
|
Text,
|
|
96378
96527
|
{
|
|
96379
96528
|
color,
|
|
@@ -96384,8 +96533,8 @@ function ContextMenuOverlay({ actions, selectedIndex }) {
|
|
|
96384
96533
|
)
|
|
96385
96534
|
] }, action.key);
|
|
96386
96535
|
}),
|
|
96387
|
-
/* @__PURE__ */ (0,
|
|
96388
|
-
/* @__PURE__ */ (0,
|
|
96536
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { children: "" }),
|
|
96537
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { color: "gray", dimColor: true, children: "j/k select Enter run Esc close" })
|
|
96389
96538
|
]
|
|
96390
96539
|
}
|
|
96391
96540
|
);
|
|
@@ -96393,7 +96542,7 @@ function ContextMenuOverlay({ actions, selectedIndex }) {
|
|
|
96393
96542
|
|
|
96394
96543
|
// src/dashboard/ink/ConfirmOverlay.tsx
|
|
96395
96544
|
await init_build2();
|
|
96396
|
-
var
|
|
96545
|
+
var import_jsx_runtime10 = __toESM(require_jsx_runtime(), 1);
|
|
96397
96546
|
var SEVERITY_CONFIG = {
|
|
96398
96547
|
low: { borderColor: "yellow", icon: "\u26A0", title: "Confirm", warning: "" },
|
|
96399
96548
|
high: { borderColor: "red", icon: "\u2717", title: "Destructive Action", warning: " This cannot be undone." },
|
|
@@ -96402,7 +96551,7 @@ var SEVERITY_CONFIG = {
|
|
|
96402
96551
|
function ConfirmOverlay({ message, severity }) {
|
|
96403
96552
|
const config = SEVERITY_CONFIG[severity];
|
|
96404
96553
|
const color = config.borderColor;
|
|
96405
|
-
return /* @__PURE__ */ (0,
|
|
96554
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
96406
96555
|
Box_default,
|
|
96407
96556
|
{
|
|
96408
96557
|
position: "absolute",
|
|
@@ -96414,19 +96563,19 @@ function ConfirmOverlay({ message, severity }) {
|
|
|
96414
96563
|
paddingX: 2,
|
|
96415
96564
|
paddingY: 1,
|
|
96416
96565
|
children: [
|
|
96417
|
-
/* @__PURE__ */ (0,
|
|
96418
|
-
/* @__PURE__ */ (0,
|
|
96419
|
-
/* @__PURE__ */ (0,
|
|
96566
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Box_default, { children: [
|
|
96567
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Text, { color, bold: true, children: `${config.icon} ` }),
|
|
96568
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Text, { bold: true, color, children: config.title })
|
|
96420
96569
|
] }),
|
|
96421
|
-
/* @__PURE__ */ (0,
|
|
96422
|
-
/* @__PURE__ */ (0,
|
|
96423
|
-
config.warning ? /* @__PURE__ */ (0,
|
|
96424
|
-
/* @__PURE__ */ (0,
|
|
96425
|
-
/* @__PURE__ */ (0,
|
|
96426
|
-
/* @__PURE__ */ (0,
|
|
96427
|
-
/* @__PURE__ */ (0,
|
|
96428
|
-
/* @__PURE__ */ (0,
|
|
96429
|
-
/* @__PURE__ */ (0,
|
|
96570
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Text, { children: "" }),
|
|
96571
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Text, { bold: true, children: ` ${message}` }),
|
|
96572
|
+
config.warning ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Text, { color: "gray", dimColor: true, children: config.warning }) : null,
|
|
96573
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Text, { children: "" }),
|
|
96574
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Box_default, { children: [
|
|
96575
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Text, { backgroundColor: severity === "low" ? "yellow" : "green", color: severity === "low" ? "black" : "white", bold: true, children: " y Yes " }),
|
|
96576
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Text, { children: " " }),
|
|
96577
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Text, { backgroundColor: "red", color: "white", bold: true, children: " n No " }),
|
|
96578
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Text, { color: "gray", dimColor: true, children: " or Esc to cancel" })
|
|
96430
96579
|
] })
|
|
96431
96580
|
]
|
|
96432
96581
|
}
|
|
@@ -96436,7 +96585,7 @@ function ConfirmOverlay({ message, severity }) {
|
|
|
96436
96585
|
// src/dashboard/ink/ToastNotification.tsx
|
|
96437
96586
|
var import_react33 = __toESM(require_react(), 1);
|
|
96438
96587
|
await init_build2();
|
|
96439
|
-
var
|
|
96588
|
+
var import_jsx_runtime11 = __toESM(require_jsx_runtime(), 1);
|
|
96440
96589
|
var SEVERITY_COLORS2 = {
|
|
96441
96590
|
error: "red",
|
|
96442
96591
|
warning: "yellow",
|
|
@@ -96464,43 +96613,43 @@ function ToastNotification({ toast }) {
|
|
|
96464
96613
|
};
|
|
96465
96614
|
const icon = SEVERITY_ICONS[toast.severity] || "";
|
|
96466
96615
|
const textColor = toast.severity === "warning" ? "black" : "white";
|
|
96467
|
-
return /* @__PURE__ */ (0,
|
|
96616
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { position: "absolute", marginTop: 0, justifyContent: "flex-end", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { backgroundColor: SEVERITY_COLORS2[toast.severity] || "white", color: textColor, bold: true, children: ` ${icon} ${toast.message} ` }) });
|
|
96468
96617
|
}
|
|
96469
96618
|
|
|
96470
96619
|
// src/dashboard/ink/TooSmallOverlay.tsx
|
|
96471
96620
|
await init_build2();
|
|
96472
|
-
var
|
|
96473
|
-
var
|
|
96621
|
+
var import_sidekick_docker_shared11 = __toESM(require_dist(), 1);
|
|
96622
|
+
var import_jsx_runtime12 = __toESM(require_jsx_runtime(), 1);
|
|
96474
96623
|
function TooSmallOverlay({ columns, rows }) {
|
|
96475
96624
|
const needWidth = Math.max(0, 60 - columns);
|
|
96476
96625
|
const needHeight = Math.max(0, 15 - rows);
|
|
96477
96626
|
const hints = [];
|
|
96478
96627
|
if (needWidth > 0) hints.push(`${needWidth} col${needWidth > 1 ? "s" : ""} wider`);
|
|
96479
96628
|
if (needHeight > 0) hints.push(`${needHeight} row${needHeight > 1 ? "s" : ""} taller`);
|
|
96480
|
-
return /* @__PURE__ */ (0,
|
|
96481
|
-
/* @__PURE__ */ (0,
|
|
96482
|
-
/* @__PURE__ */ (0,
|
|
96483
|
-
/* @__PURE__ */ (0,
|
|
96484
|
-
/* @__PURE__ */ (0,
|
|
96485
|
-
/* @__PURE__ */ (0,
|
|
96486
|
-
/* @__PURE__ */ (0,
|
|
96629
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Box_default, { flexDirection: "column", justifyContent: "center", alignItems: "center", height: rows, width: columns, children: [
|
|
96630
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { bold: true, color: "magenta", children: `\u26A1 ${import_sidekick_docker_shared11.BRAND_INLINE}` }),
|
|
96631
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { children: "" }),
|
|
96632
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { color: "yellow", bold: true, children: "Terminal too small" }),
|
|
96633
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { color: "gray", children: `${columns}\xD7${rows} \u2192 need ${hints.join(" and ")}` }),
|
|
96634
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { children: "" }),
|
|
96635
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { color: "gray", dimColor: true, children: "Resize to at least 60\xD715 to continue." })
|
|
96487
96636
|
] });
|
|
96488
96637
|
}
|
|
96489
96638
|
|
|
96490
96639
|
// src/dashboard/ink/ExecOverlay.tsx
|
|
96491
96640
|
await init_build2();
|
|
96492
|
-
var
|
|
96641
|
+
var import_jsx_runtime13 = __toESM(require_jsx_runtime(), 1);
|
|
96493
96642
|
function ExecOverlay({ containerName, outputLines }) {
|
|
96494
96643
|
const { rows } = useTerminalSize();
|
|
96495
96644
|
const viewportHeight = Math.max(1, rows - 3);
|
|
96496
96645
|
const scrollOffset = Math.max(0, outputLines.length - viewportHeight);
|
|
96497
96646
|
const visibleLines = outputLines.slice(scrollOffset, scrollOffset + viewportHeight);
|
|
96498
|
-
return /* @__PURE__ */ (0,
|
|
96499
|
-
/* @__PURE__ */ (0,
|
|
96500
|
-
/* @__PURE__ */ (0,
|
|
96501
|
-
/* @__PURE__ */ (0,
|
|
96647
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Box_default, { flexDirection: "column", flexGrow: 1, children: [
|
|
96648
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Box_default, { children: [
|
|
96649
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { bold: true, color: "#2B4C7E", children: ` Exec: ${containerName} ` }),
|
|
96650
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { color: "gray", children: " (Ctrl+] to detach)" })
|
|
96502
96651
|
] }),
|
|
96503
|
-
/* @__PURE__ */ (0,
|
|
96652
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Box_default, { flexDirection: "column", flexGrow: 1, children: visibleLines.map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { children: line || " " }, scrollOffset + i)) })
|
|
96504
96653
|
] });
|
|
96505
96654
|
}
|
|
96506
96655
|
|
|
@@ -96574,7 +96723,7 @@ function parseMouseEvent(data) {
|
|
|
96574
96723
|
// src/dashboard/ink/mouse/MouseProvider.tsx
|
|
96575
96724
|
var import_react34 = __toESM(require_react(), 1);
|
|
96576
96725
|
await init_build2();
|
|
96577
|
-
var
|
|
96726
|
+
var import_jsx_runtime14 = __toESM(require_jsx_runtime(), 1);
|
|
96578
96727
|
function InputSink() {
|
|
96579
96728
|
use_input_default(() => {
|
|
96580
96729
|
});
|
|
@@ -96598,47 +96747,47 @@ function MouseProvider({ onMouse, children }) {
|
|
|
96598
96747
|
disableMouse();
|
|
96599
96748
|
};
|
|
96600
96749
|
}, [onMouse]);
|
|
96601
|
-
return /* @__PURE__ */ (0,
|
|
96602
|
-
/* @__PURE__ */ (0,
|
|
96750
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
96751
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(InputSink, {}),
|
|
96603
96752
|
children
|
|
96604
96753
|
] });
|
|
96605
96754
|
}
|
|
96606
96755
|
|
|
96607
96756
|
// src/dashboard/ink/LogFilterOverlay.tsx
|
|
96608
96757
|
await init_build2();
|
|
96609
|
-
var
|
|
96758
|
+
var import_jsx_runtime15 = __toESM(require_jsx_runtime(), 1);
|
|
96610
96759
|
function LogFilterOverlay({ filterString, filterMode }) {
|
|
96611
96760
|
const modeLabel = filterMode === "exact" ? "exact" : "fuzzy";
|
|
96612
|
-
return /* @__PURE__ */ (0,
|
|
96613
|
-
/* @__PURE__ */ (0,
|
|
96614
|
-
/* @__PURE__ */ (0,
|
|
96761
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Box_default, { position: "absolute", marginTop: 1, marginLeft: 1, children: [
|
|
96762
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Text, { backgroundColor: "#2B4C7E", color: "white", bold: true, children: ` Log filter (${modeLabel}): ${filterString}\u2588 ` }),
|
|
96763
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Text, { color: "gray", children: " Tab: toggle mode Enter: apply Esc: clear" })
|
|
96615
96764
|
] });
|
|
96616
96765
|
}
|
|
96617
96766
|
|
|
96618
96767
|
// src/dashboard/ink/VersionOverlay.tsx
|
|
96619
96768
|
var import_react35 = __toESM(require_react(), 1);
|
|
96620
96769
|
await init_build2();
|
|
96621
|
-
var
|
|
96622
|
-
var
|
|
96770
|
+
var import_sidekick_docker_shared12 = __toESM(require_dist(), 1);
|
|
96771
|
+
var import_jsx_runtime16 = __toESM(require_jsx_runtime(), 1);
|
|
96623
96772
|
function VersionOverlay({ version: version2 }) {
|
|
96624
|
-
const phrase = import_react35.default.useMemo(() => (0,
|
|
96625
|
-
return /* @__PURE__ */ (0,
|
|
96626
|
-
/* @__PURE__ */ (0,
|
|
96627
|
-
/* @__PURE__ */ (0,
|
|
96628
|
-
/* @__PURE__ */ (0,
|
|
96629
|
-
/* @__PURE__ */ (0,
|
|
96630
|
-
/* @__PURE__ */ (0,
|
|
96631
|
-
/* @__PURE__ */ (0,
|
|
96632
|
-
/* @__PURE__ */ (0,
|
|
96633
|
-
/* @__PURE__ */ (0,
|
|
96634
|
-
/* @__PURE__ */ (0,
|
|
96635
|
-
/* @__PURE__ */ (0,
|
|
96773
|
+
const phrase = import_react35.default.useMemo(() => (0, import_sidekick_docker_shared12.getRandomPhrase)(), []);
|
|
96774
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Box_default, { flexDirection: "column", flexGrow: 1, padding: 1, children: [
|
|
96775
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Text, { bold: true, color: "magenta", children: `\u26A1 ${import_sidekick_docker_shared12.BRAND_INLINE}` }),
|
|
96776
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Text, { color: "#2B4C7E", bold: true, children: `${import_sidekick_docker_shared12.BRAND_TAGLINE} v${version2}` }),
|
|
96777
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Text, { children: "" }),
|
|
96778
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Text, { color: "gray", dimColor: true, children: "\u2500".repeat(40) }),
|
|
96779
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Text, { children: "" }),
|
|
96780
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Text, { color: "gray", italic: true, children: ` "${phrase}"` }),
|
|
96781
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Text, { children: "" }),
|
|
96782
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Text, { color: "gray", dimColor: true, children: "\u2500".repeat(40) }),
|
|
96783
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Text, { children: "" }),
|
|
96784
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Text, { color: "gray", dimColor: true, children: "Press V or Esc to close" })
|
|
96636
96785
|
] });
|
|
96637
96786
|
}
|
|
96638
96787
|
|
|
96639
96788
|
// src/dashboard/ink/SortOverlay.tsx
|
|
96640
96789
|
await init_build2();
|
|
96641
|
-
var
|
|
96790
|
+
var import_jsx_runtime17 = __toESM(require_jsx_runtime(), 1);
|
|
96642
96791
|
var SORT_OPTIONS = [
|
|
96643
96792
|
{ field: "state", label: "State (running first)" },
|
|
96644
96793
|
{ field: "name", label: "Name" },
|
|
@@ -96649,7 +96798,7 @@ var SORT_OPTIONS = [
|
|
|
96649
96798
|
{ field: "pids", label: "PIDs" }
|
|
96650
96799
|
];
|
|
96651
96800
|
function SortOverlay({ selectedIndex, currentField, reversed }) {
|
|
96652
|
-
return /* @__PURE__ */ (0,
|
|
96801
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
96653
96802
|
Box_default,
|
|
96654
96803
|
{
|
|
96655
96804
|
position: "absolute",
|
|
@@ -96660,12 +96809,12 @@ function SortOverlay({ selectedIndex, currentField, reversed }) {
|
|
|
96660
96809
|
borderColor: "#2B4C7E",
|
|
96661
96810
|
paddingX: 1,
|
|
96662
96811
|
children: [
|
|
96663
|
-
/* @__PURE__ */ (0,
|
|
96812
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Text, { bold: true, color: "#2B4C7E", children: "\u2195 Sort by" }),
|
|
96664
96813
|
SORT_OPTIONS.map((opt, i) => {
|
|
96665
96814
|
const isSelected = i === selectedIndex;
|
|
96666
96815
|
const isCurrent = opt.field === currentField;
|
|
96667
96816
|
const indicator = isCurrent ? reversed ? " \u25B2" : " \u25BC" : "";
|
|
96668
|
-
return /* @__PURE__ */ (0,
|
|
96817
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
96669
96818
|
Text,
|
|
96670
96819
|
{
|
|
96671
96820
|
color: isSelected ? "#2B4C7E" : isCurrent ? "yellow" : "white",
|
|
@@ -96675,15 +96824,15 @@ function SortOverlay({ selectedIndex, currentField, reversed }) {
|
|
|
96675
96824
|
}
|
|
96676
96825
|
) }, opt.field);
|
|
96677
96826
|
}),
|
|
96678
|
-
/* @__PURE__ */ (0,
|
|
96679
|
-
/* @__PURE__ */ (0,
|
|
96827
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Text, { children: "" }),
|
|
96828
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Text, { color: "gray", dimColor: true, children: "j/k select Enter apply R reverse Esc close" })
|
|
96680
96829
|
]
|
|
96681
96830
|
}
|
|
96682
96831
|
);
|
|
96683
96832
|
}
|
|
96684
96833
|
|
|
96685
96834
|
// src/dashboard/ink/Dashboard.tsx
|
|
96686
|
-
var
|
|
96835
|
+
var import_sidekick_docker_shared13 = __toESM(require_dist(), 1);
|
|
96687
96836
|
|
|
96688
96837
|
// src/dashboard/ExecManager.ts
|
|
96689
96838
|
var ExecManager = class {
|
|
@@ -96740,7 +96889,7 @@ var ExecManager = class {
|
|
|
96740
96889
|
};
|
|
96741
96890
|
|
|
96742
96891
|
// src/dashboard/ink/Dashboard.tsx
|
|
96743
|
-
var
|
|
96892
|
+
var import_jsx_runtime18 = __toESM(require_jsx_runtime(), 1);
|
|
96744
96893
|
var SORT_FIELDS2 = ["state", "name", "cpu", "mem", "net", "io", "pids"];
|
|
96745
96894
|
var SIDE_PANEL_WIDTH = 28;
|
|
96746
96895
|
var SIDE_PANEL_WIDTH_WIDE = 42;
|
|
@@ -96763,7 +96912,7 @@ function reducer(state, action) {
|
|
|
96763
96912
|
detailScrollPerTab: {}
|
|
96764
96913
|
};
|
|
96765
96914
|
case "SELECT_ITEM":
|
|
96766
|
-
return { ...state, selectedItemIndex: action.index, detailTabIndex: 0, detailScrollOffset: 0, detailScrollPerTab: {} };
|
|
96915
|
+
return { ...state, selectedItemIndex: action.index, detailTabIndex: 0, detailScrollOffset: 0, detailScrollPerTab: {}, secondaryDetailScrollOffset: 0 };
|
|
96767
96916
|
case "SET_DETAIL_TAB": {
|
|
96768
96917
|
const saved = { ...state.detailScrollPerTab, [state.detailTabIndex]: state.detailScrollOffset };
|
|
96769
96918
|
return { ...state, detailTabIndex: action.index, detailScrollOffset: saved[action.index] ?? 0, detailScrollPerTab: saved };
|
|
@@ -96842,6 +96991,22 @@ function reducer(state, action) {
|
|
|
96842
96991
|
const next = (state.sortMenuIndex + action.delta + SORT_FIELDS2.length) % SORT_FIELDS2.length;
|
|
96843
96992
|
return { ...state, sortMenuIndex: next };
|
|
96844
96993
|
}
|
|
96994
|
+
case "PIN_COMPARE": {
|
|
96995
|
+
const current = state.compareItemIds[action.panelId] ?? null;
|
|
96996
|
+
const newId = current === action.itemId ? null : action.itemId;
|
|
96997
|
+
return {
|
|
96998
|
+
...state,
|
|
96999
|
+
compareItemIds: { ...state.compareItemIds, [action.panelId]: newId },
|
|
97000
|
+
secondaryDetailScrollOffset: 0
|
|
97001
|
+
};
|
|
97002
|
+
}
|
|
97003
|
+
case "SCROLL_SECONDARY_DETAIL":
|
|
97004
|
+
return { ...state, secondaryDetailScrollOffset: action.offset };
|
|
97005
|
+
case "SCROLL_SECONDARY_DETAIL_DELTA": {
|
|
97006
|
+
const maxOffset = Math.max(0, action.totalLines - action.viewportHeight);
|
|
97007
|
+
const next = Math.max(0, Math.min(state.secondaryDetailScrollOffset + action.delta, maxOffset));
|
|
97008
|
+
return { ...state, secondaryDetailScrollOffset: next };
|
|
97009
|
+
}
|
|
96845
97010
|
default:
|
|
96846
97011
|
return state;
|
|
96847
97012
|
}
|
|
@@ -96869,18 +97034,20 @@ var initialState = {
|
|
|
96869
97034
|
showAllContainers: true,
|
|
96870
97035
|
sortField: "state",
|
|
96871
97036
|
sortReversed: false,
|
|
96872
|
-
sortMenuIndex: 0
|
|
97037
|
+
sortMenuIndex: 0,
|
|
97038
|
+
compareItemIds: {},
|
|
97039
|
+
secondaryDetailScrollOffset: 0
|
|
96873
97040
|
};
|
|
96874
97041
|
function Dashboard({ panels, metrics, onViewStateChange, execTriggerRef, onExecFallback }) {
|
|
96875
97042
|
const [state, dispatch] = (0, import_react36.useReducer)(reducer, initialState);
|
|
96876
97043
|
const { columns, rows } = useTerminalSize();
|
|
96877
97044
|
const toastIdRef = (0, import_react36.useRef)(0);
|
|
96878
97045
|
const execManagerRef = (0, import_react36.useRef)(null);
|
|
96879
|
-
const [phrase, setPhrase] = import_react36.default.useState(() => (0,
|
|
97046
|
+
const [phrase, setPhrase] = import_react36.default.useState(() => (0, import_sidekick_docker_shared13.getRandomPhrase)());
|
|
96880
97047
|
const phraseTimerRef = (0, import_react36.useRef)(null);
|
|
96881
97048
|
const rotatePhraseRef = (0, import_react36.useRef)(void 0);
|
|
96882
97049
|
rotatePhraseRef.current = () => {
|
|
96883
|
-
setPhrase((0,
|
|
97050
|
+
setPhrase((0, import_sidekick_docker_shared13.getRandomPhrase)());
|
|
96884
97051
|
if (phraseTimerRef.current) clearTimeout(phraseTimerRef.current);
|
|
96885
97052
|
phraseTimerRef.current = setTimeout(() => rotatePhraseRef.current?.(), 7e3);
|
|
96886
97053
|
};
|
|
@@ -97035,14 +97202,21 @@ function Dashboard({ panels, metrics, onViewStateChange, execTriggerRef, onExecF
|
|
|
97035
97202
|
const selectedItem = currentItems[clampedSelection];
|
|
97036
97203
|
const detailTabs = panel.detailTabs;
|
|
97037
97204
|
const tabIdx = Math.min(state.detailTabIndex, detailTabs.length - 1);
|
|
97205
|
+
const compareItemId = state.compareItemIds[panel.id] ?? null;
|
|
97206
|
+
(0, import_react36.useEffect)(() => {
|
|
97207
|
+
if (compareItemId && selectedItem?.id === compareItemId) {
|
|
97208
|
+
dispatch({ type: "PIN_COMPARE", panelId: panel.id, itemId: compareItemId });
|
|
97209
|
+
}
|
|
97210
|
+
}, [selectedItem?.id, compareItemId, panel.id]);
|
|
97038
97211
|
(0, import_react36.useEffect)(() => {
|
|
97039
97212
|
onViewStateChange?.({
|
|
97040
97213
|
panelId: panel.id,
|
|
97041
97214
|
itemId: selectedItem?.id ?? null,
|
|
97042
97215
|
detailTabIndex: tabIdx,
|
|
97043
|
-
sortField: state.sortField
|
|
97216
|
+
sortField: state.sortField,
|
|
97217
|
+
compareItemId
|
|
97044
97218
|
});
|
|
97045
|
-
}, [panel.id, selectedItem?.id, tabIdx, state.sortField]);
|
|
97219
|
+
}, [panel.id, selectedItem?.id, tabIdx, state.sortField, compareItemId]);
|
|
97046
97220
|
const enrichedMetrics = {
|
|
97047
97221
|
...metrics,
|
|
97048
97222
|
logFilterString: state.logFilterString,
|
|
@@ -97063,6 +97237,31 @@ function Dashboard({ panels, metrics, onViewStateChange, execTriggerRef, onExecF
|
|
|
97063
97237
|
dispatch({ type: "SCROLL_DETAIL", offset: detailLines.length - detailViewportHeight });
|
|
97064
97238
|
}
|
|
97065
97239
|
}, [shouldAutoScroll, detailLines.length, detailViewportHeight]);
|
|
97240
|
+
const isCompareActive = compareItemId != null && shouldAutoScroll;
|
|
97241
|
+
const secondaryDetailLines = import_react36.default.useMemo(() => {
|
|
97242
|
+
if (!isCompareActive) return [];
|
|
97243
|
+
if (panel.id === "containers") {
|
|
97244
|
+
const logs = enrichedMetrics.secondaryContainerLogs;
|
|
97245
|
+
if (logs.length === 0) return ["Waiting for logs..."];
|
|
97246
|
+
return renderLogLines(logs, state.logFilterString, state.logFilterMode, enrichedMetrics.secondaryLogSeverityCounts);
|
|
97247
|
+
}
|
|
97248
|
+
if (panel.id === "services") {
|
|
97249
|
+
const logs = enrichedMetrics.secondaryComposeLogs;
|
|
97250
|
+
if (logs.length === 0) return ["Waiting for logs..."];
|
|
97251
|
+
return renderLogLines(logs, state.logFilterString, state.logFilterMode);
|
|
97252
|
+
}
|
|
97253
|
+
return [];
|
|
97254
|
+
}, [isCompareActive, panel.id, enrichedMetrics.secondaryContainerLogs, enrichedMetrics.secondaryComposeLogs, enrichedMetrics.secondaryLogSeverityCounts, state.logFilterString, state.logFilterMode]);
|
|
97255
|
+
(0, import_react36.useEffect)(() => {
|
|
97256
|
+
if (isCompareActive && secondaryDetailLines.length > detailViewportHeight) {
|
|
97257
|
+
dispatch({ type: "SCROLL_SECONDARY_DETAIL", offset: secondaryDetailLines.length - detailViewportHeight });
|
|
97258
|
+
}
|
|
97259
|
+
}, [isCompareActive, secondaryDetailLines.length, detailViewportHeight]);
|
|
97260
|
+
const compareItemLabel = import_react36.default.useMemo(() => {
|
|
97261
|
+
if (!compareItemId) return "";
|
|
97262
|
+
const item = currentItems.find((it) => it.id === compareItemId);
|
|
97263
|
+
return item ? item.label.replace(/^[^\w]*/, "").trim() : compareItemId.slice(0, 12);
|
|
97264
|
+
}, [compareItemId, currentItems]);
|
|
97066
97265
|
const panelActions = panel.getActions();
|
|
97067
97266
|
const applicableActions = selectedItem ? panelActions.filter((a) => !a.condition || a.condition(selectedItem)) : [];
|
|
97068
97267
|
const contextActions = state.overlay === "context-menu" ? applicableActions : [];
|
|
@@ -97110,27 +97309,35 @@ function Dashboard({ panels, metrics, onViewStateChange, execTriggerRef, onExecF
|
|
|
97110
97309
|
sideScroll,
|
|
97111
97310
|
addToast,
|
|
97112
97311
|
removeToast,
|
|
97113
|
-
rotatePhrase
|
|
97312
|
+
rotatePhrase,
|
|
97313
|
+
secondaryDetailLineCount: secondaryDetailLines.length
|
|
97114
97314
|
});
|
|
97115
97315
|
if (tooSmall) {
|
|
97116
|
-
return /* @__PURE__ */ (0,
|
|
97316
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TooSmallOverlay, { columns, rows });
|
|
97117
97317
|
}
|
|
97118
97318
|
const showNormalLayout = state.overlay !== "help" && state.overlay !== "exec" && state.overlay !== "version";
|
|
97119
97319
|
const panelActionHints = applicableActions.length > 0 ? [{ key: "x", label: "Actions", destructive: false }] : [];
|
|
97120
97320
|
const contextHint = (() => {
|
|
97121
97321
|
if (panel.id === "containers") {
|
|
97122
97322
|
const parts = [];
|
|
97123
|
-
if (tabIdx === 0)
|
|
97323
|
+
if (tabIdx === 0) {
|
|
97324
|
+
parts.push("f:Filter", "c:Copy", "m:Compare");
|
|
97325
|
+
}
|
|
97124
97326
|
parts.push(state.showAllContainers ? "a:All" : "a:Running");
|
|
97125
97327
|
parts.push(`o:\u2195${state.sortField}`);
|
|
97126
97328
|
return parts.join(" ");
|
|
97127
97329
|
}
|
|
97330
|
+
if (panel.id === "services") {
|
|
97331
|
+
const parts = [];
|
|
97332
|
+
if (tabIdx === 1) parts.push("m:Compare");
|
|
97333
|
+
return parts.join(" ");
|
|
97334
|
+
}
|
|
97128
97335
|
return "";
|
|
97129
97336
|
})();
|
|
97130
|
-
return /* @__PURE__ */ (0,
|
|
97131
|
-
showNormalLayout && /* @__PURE__ */ (0,
|
|
97132
|
-
showNormalLayout && /* @__PURE__ */ (0,
|
|
97133
|
-
sideWidth > 0 && /* @__PURE__ */ (0,
|
|
97337
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(MouseProvider, { onMouse: handleMouse, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Box_default, { flexDirection: "column", height: rows, width: columns, children: [
|
|
97338
|
+
showNormalLayout && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TabBar, { panels, activeIndex: state.activePanelIndex, layoutMode: state.layoutMode, phrase, panelCounts }),
|
|
97339
|
+
showNormalLayout && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Box_default, { flexGrow: 1, flexDirection: "row", children: [
|
|
97340
|
+
sideWidth > 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
97134
97341
|
SideList,
|
|
97135
97342
|
{
|
|
97136
97343
|
items: currentItems,
|
|
@@ -97143,12 +97350,26 @@ function Dashboard({ panels, metrics, onViewStateChange, execTriggerRef, onExecF
|
|
|
97143
97350
|
filterString: state.filterString || void 0,
|
|
97144
97351
|
panelId: panel.id,
|
|
97145
97352
|
totalCount: totalItemCount,
|
|
97146
|
-
runningCount: panel.id === "containers" ? runningCount : void 0
|
|
97353
|
+
runningCount: panel.id === "containers" ? runningCount : void 0,
|
|
97354
|
+
compareItemId: compareItemId || void 0
|
|
97147
97355
|
}
|
|
97148
97356
|
),
|
|
97149
|
-
/* @__PURE__ */ (0,
|
|
97150
|
-
/* @__PURE__ */ (0,
|
|
97151
|
-
/* @__PURE__ */ (0,
|
|
97357
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Box_default, { flexDirection: "column", flexGrow: 1, children: [
|
|
97358
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DetailTabBar, { tabs: detailTabs, activeIndex: state.detailTabIndex }),
|
|
97359
|
+
isCompareActive ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
97360
|
+
CompareDetailPane,
|
|
97361
|
+
{
|
|
97362
|
+
primaryLines: detailLines,
|
|
97363
|
+
secondaryLines: secondaryDetailLines,
|
|
97364
|
+
primaryScrollOffset: state.detailScrollOffset,
|
|
97365
|
+
secondaryScrollOffset: state.secondaryDetailScrollOffset,
|
|
97366
|
+
viewportHeight: detailViewportHeight,
|
|
97367
|
+
totalWidth: columns - sideWidth,
|
|
97368
|
+
focused: state.focusTarget === "detail",
|
|
97369
|
+
primaryLabel: selectedItem?.label.replace(/^[^\w]*/, "").trim() ?? "",
|
|
97370
|
+
secondaryLabel: compareItemLabel
|
|
97371
|
+
}
|
|
97372
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
97152
97373
|
DetailPane,
|
|
97153
97374
|
{
|
|
97154
97375
|
lines: detailLines,
|
|
@@ -97159,16 +97380,16 @@ function Dashboard({ panels, metrics, onViewStateChange, execTriggerRef, onExecF
|
|
|
97159
97380
|
)
|
|
97160
97381
|
] })
|
|
97161
97382
|
] }),
|
|
97162
|
-
state.overlay === "help" && /* @__PURE__ */ (0,
|
|
97163
|
-
state.overlay === "version" && /* @__PURE__ */ (0,
|
|
97164
|
-
state.overlay === "exec" && /* @__PURE__ */ (0,
|
|
97383
|
+
state.overlay === "help" && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(HelpOverlay, { panels, activePanelIndex: state.activePanelIndex, version: "0.2.3" }),
|
|
97384
|
+
state.overlay === "version" && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VersionOverlay, { version: "0.2.3" }),
|
|
97385
|
+
state.overlay === "exec" && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
97165
97386
|
ExecOverlay,
|
|
97166
97387
|
{
|
|
97167
97388
|
containerName: state.execContainerName,
|
|
97168
97389
|
outputLines: state.execOutputLines
|
|
97169
97390
|
}
|
|
97170
97391
|
),
|
|
97171
|
-
state.overlay !== "exec" && /* @__PURE__ */ (0,
|
|
97392
|
+
state.overlay !== "exec" && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
97172
97393
|
StatusBar,
|
|
97173
97394
|
{
|
|
97174
97395
|
daemonConnected: metrics.daemonConnected,
|
|
@@ -97177,15 +97398,15 @@ function Dashboard({ panels, metrics, onViewStateChange, execTriggerRef, onExecF
|
|
|
97177
97398
|
filterString: state.filterString,
|
|
97178
97399
|
containerCount: metrics.containers.length,
|
|
97179
97400
|
runningCount,
|
|
97180
|
-
version: "0.2.
|
|
97401
|
+
version: "0.2.3",
|
|
97181
97402
|
matchCount: state.filterString ? currentItems.length : void 0,
|
|
97182
97403
|
totalCount: state.filterString ? totalItemCount : void 0,
|
|
97183
97404
|
lastRefresh: metrics.lastRefresh,
|
|
97184
97405
|
contextHint
|
|
97185
97406
|
}
|
|
97186
97407
|
),
|
|
97187
|
-
state.overlay === "context-menu" && /* @__PURE__ */ (0,
|
|
97188
|
-
state.overlay === "filter" && /* @__PURE__ */ (0,
|
|
97408
|
+
state.overlay === "context-menu" && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ContextMenuOverlay, { actions: contextActions, selectedIndex: state.contextMenuIndex }),
|
|
97409
|
+
state.overlay === "filter" && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
97189
97410
|
FilterOverlay,
|
|
97190
97411
|
{
|
|
97191
97412
|
filterString: state.filterString,
|
|
@@ -97194,15 +97415,15 @@ function Dashboard({ panels, metrics, onViewStateChange, execTriggerRef, onExecF
|
|
|
97194
97415
|
panelTitle: panel.title
|
|
97195
97416
|
}
|
|
97196
97417
|
),
|
|
97197
|
-
state.overlay === "log-filter" && /* @__PURE__ */ (0,
|
|
97418
|
+
state.overlay === "log-filter" && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
97198
97419
|
LogFilterOverlay,
|
|
97199
97420
|
{
|
|
97200
97421
|
filterString: state.logFilterString,
|
|
97201
97422
|
filterMode: state.logFilterMode
|
|
97202
97423
|
}
|
|
97203
97424
|
),
|
|
97204
|
-
state.overlay === "sort" && /* @__PURE__ */ (0,
|
|
97205
|
-
state.overlay === "confirm" && /* @__PURE__ */ (0,
|
|
97425
|
+
state.overlay === "sort" && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SortOverlay, { selectedIndex: state.sortMenuIndex, currentField: state.sortField, reversed: state.sortReversed }),
|
|
97426
|
+
state.overlay === "confirm" && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
97206
97427
|
ConfirmOverlay,
|
|
97207
97428
|
{
|
|
97208
97429
|
message: state.confirmMessage,
|
|
@@ -97214,7 +97435,7 @@ function Dashboard({ panels, metrics, onViewStateChange, execTriggerRef, onExecF
|
|
|
97214
97435
|
onCancel: () => dispatch({ type: "SET_CONFIRM", action: null, message: "" })
|
|
97215
97436
|
}
|
|
97216
97437
|
),
|
|
97217
|
-
state.toasts.length > 0 && /* @__PURE__ */ (0,
|
|
97438
|
+
state.toasts.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ToastNotification, { toast: state.toasts[state.toasts.length - 1] })
|
|
97218
97439
|
] }) });
|
|
97219
97440
|
}
|
|
97220
97441
|
|
|
@@ -97222,7 +97443,7 @@ function Dashboard({ panels, metrics, onViewStateChange, execTriggerRef, onExecF
|
|
|
97222
97443
|
async function dashboardAction(_opts, cmd) {
|
|
97223
97444
|
const globalOpts = cmd.parent?.opts() ?? cmd.opts();
|
|
97224
97445
|
const socketPath = globalOpts.socket;
|
|
97225
|
-
const client = new
|
|
97446
|
+
const client = new import_sidekick_docker_shared14.DockerClient(socketPath ? { socketPath } : void 0);
|
|
97226
97447
|
const ok = await client.ping();
|
|
97227
97448
|
if (!ok) {
|
|
97228
97449
|
console.error("Error: Cannot connect to Docker daemon. Is Docker running?");
|
|
@@ -97231,7 +97452,7 @@ async function dashboardAction(_opts, cmd) {
|
|
|
97231
97452
|
const cwd2 = process.cwd();
|
|
97232
97453
|
const state = new DockerState(client, cwd2);
|
|
97233
97454
|
await state.refresh();
|
|
97234
|
-
const composeClient = new
|
|
97455
|
+
const composeClient = new import_sidekick_docker_shared14.ComposeClient();
|
|
97235
97456
|
const onAction = () => {
|
|
97236
97457
|
state.refresh().then(() => scheduleRender()).catch((e) => console.debug("refresh failed:", e));
|
|
97237
97458
|
};
|
|
@@ -97240,6 +97461,8 @@ async function dashboardAction(_opts, cmd) {
|
|
|
97240
97461
|
};
|
|
97241
97462
|
let logFlushTimer = null;
|
|
97242
97463
|
let composeLogFlushTimer = null;
|
|
97464
|
+
let secondaryLogFlushTimer = null;
|
|
97465
|
+
let secondaryComposeLogFlushTimer = null;
|
|
97243
97466
|
const logManager = new LogStreamManager(client, () => {
|
|
97244
97467
|
if (logFlushTimer) return;
|
|
97245
97468
|
logFlushTimer = setTimeout(() => {
|
|
@@ -97259,6 +97482,25 @@ async function dashboardAction(_opts, cmd) {
|
|
|
97259
97482
|
scheduleRender();
|
|
97260
97483
|
};
|
|
97261
97484
|
let logSeverityCounts = logManager.getSeverityCounts();
|
|
97485
|
+
const secondaryLogManager = new LogStreamManager(client, () => {
|
|
97486
|
+
if (secondaryLogFlushTimer) return;
|
|
97487
|
+
secondaryLogFlushTimer = setTimeout(() => {
|
|
97488
|
+
secondaryLogFlushTimer = null;
|
|
97489
|
+
state.setSecondaryLogs(secondaryLogManager.getLogs());
|
|
97490
|
+
secondaryLogSeverityCounts = secondaryLogManager.getSeverityCounts();
|
|
97491
|
+
scheduleRender();
|
|
97492
|
+
}, 100);
|
|
97493
|
+
});
|
|
97494
|
+
const flushSecondaryLogsNow = () => {
|
|
97495
|
+
if (secondaryLogFlushTimer) {
|
|
97496
|
+
clearTimeout(secondaryLogFlushTimer);
|
|
97497
|
+
secondaryLogFlushTimer = null;
|
|
97498
|
+
}
|
|
97499
|
+
state.setSecondaryLogs(secondaryLogManager.getLogs());
|
|
97500
|
+
secondaryLogSeverityCounts = secondaryLogManager.getSeverityCounts();
|
|
97501
|
+
scheduleRender();
|
|
97502
|
+
};
|
|
97503
|
+
let secondaryLogSeverityCounts = secondaryLogManager.getSeverityCounts();
|
|
97262
97504
|
const statsManager = new StatsStreamManager(client, state.getStatsCollector(), () => {
|
|
97263
97505
|
scheduleRender();
|
|
97264
97506
|
});
|
|
@@ -97284,15 +97526,35 @@ async function dashboardAction(_opts, cmd) {
|
|
|
97284
97526
|
}
|
|
97285
97527
|
scheduleRender();
|
|
97286
97528
|
};
|
|
97529
|
+
const secondaryComposeLogManager = new ComposeLogStreamManager(composeClient, () => {
|
|
97530
|
+
if (secondaryComposeLogFlushTimer) return;
|
|
97531
|
+
secondaryComposeLogFlushTimer = setTimeout(() => {
|
|
97532
|
+
secondaryComposeLogFlushTimer = null;
|
|
97533
|
+
state.setSecondaryComposeLogs(secondaryComposeLogManager.getLogs());
|
|
97534
|
+
scheduleRender();
|
|
97535
|
+
}, 100);
|
|
97536
|
+
});
|
|
97537
|
+
const flushSecondaryComposeLogsNow = () => {
|
|
97538
|
+
if (secondaryComposeLogFlushTimer) {
|
|
97539
|
+
clearTimeout(secondaryComposeLogFlushTimer);
|
|
97540
|
+
secondaryComposeLogFlushTimer = null;
|
|
97541
|
+
}
|
|
97542
|
+
state.setSecondaryComposeLogs(secondaryComposeLogManager.getLogs());
|
|
97543
|
+
scheduleRender();
|
|
97544
|
+
};
|
|
97287
97545
|
const onViewStateChange = (viewState) => {
|
|
97288
|
-
const { panelId, itemId, detailTabIndex, sortField } = viewState;
|
|
97546
|
+
const { panelId, itemId, detailTabIndex, sortField, compareItemId } = viewState;
|
|
97289
97547
|
const wantsLiveStats = sortField === "cpu" || sortField === "mem" || sortField === "net" || sortField === "io" || sortField === "pids";
|
|
97290
97548
|
if (panelId === "containers") {
|
|
97291
97549
|
void logManager.select(detailTabIndex === 0 ? itemId : null);
|
|
97292
97550
|
void statsManager.select(itemId && (detailTabIndex === 1 || wantsLiveStats) ? itemId : null);
|
|
97293
97551
|
void composeLogManager.selectCompose(null, null);
|
|
97552
|
+
void secondaryLogManager.select(detailTabIndex === 0 && compareItemId ? compareItemId : null);
|
|
97553
|
+
void secondaryComposeLogManager.selectCompose(null, null);
|
|
97294
97554
|
flushLogsNow();
|
|
97295
97555
|
flushComposeLogsNow();
|
|
97556
|
+
flushSecondaryLogsNow();
|
|
97557
|
+
flushSecondaryComposeLogsNow();
|
|
97296
97558
|
if (itemId && !state.getInspectedEnv(itemId)) {
|
|
97297
97559
|
client.getContainerEnv(itemId).then((env3) => {
|
|
97298
97560
|
state.setInspectedEnv(itemId, env3);
|
|
@@ -97308,6 +97570,7 @@ async function dashboardAction(_opts, cmd) {
|
|
|
97308
97570
|
} else if (panelId === "services" && itemId) {
|
|
97309
97571
|
void logManager.select(null);
|
|
97310
97572
|
void statsManager.select(null);
|
|
97573
|
+
void secondaryLogManager.select(null);
|
|
97311
97574
|
if (detailTabIndex === 1) {
|
|
97312
97575
|
const parts = itemId.split(":");
|
|
97313
97576
|
if (parts[0] === "project") {
|
|
@@ -97315,17 +97578,34 @@ async function dashboardAction(_opts, cmd) {
|
|
|
97315
97578
|
} else if (parts[0] === "service") {
|
|
97316
97579
|
void composeLogManager.selectCompose(parts[1], parts.slice(2).join(":"));
|
|
97317
97580
|
}
|
|
97581
|
+
if (compareItemId) {
|
|
97582
|
+
const cParts = compareItemId.split(":");
|
|
97583
|
+
if (cParts[0] === "project") {
|
|
97584
|
+
void secondaryComposeLogManager.selectCompose(cParts.slice(1).join(":"), null);
|
|
97585
|
+
} else if (cParts[0] === "service") {
|
|
97586
|
+
void secondaryComposeLogManager.selectCompose(cParts[1], cParts.slice(2).join(":"));
|
|
97587
|
+
}
|
|
97588
|
+
} else {
|
|
97589
|
+
void secondaryComposeLogManager.selectCompose(null, null);
|
|
97590
|
+
}
|
|
97318
97591
|
} else {
|
|
97319
97592
|
void composeLogManager.selectCompose(null, null);
|
|
97593
|
+
void secondaryComposeLogManager.selectCompose(null, null);
|
|
97320
97594
|
}
|
|
97321
97595
|
flushLogsNow();
|
|
97322
97596
|
flushComposeLogsNow();
|
|
97597
|
+
flushSecondaryLogsNow();
|
|
97598
|
+
flushSecondaryComposeLogsNow();
|
|
97323
97599
|
} else if (panelId === "images") {
|
|
97324
97600
|
void logManager.select(null);
|
|
97325
97601
|
void statsManager.select(null);
|
|
97326
97602
|
void composeLogManager.selectCompose(null, null);
|
|
97603
|
+
void secondaryLogManager.select(null);
|
|
97604
|
+
void secondaryComposeLogManager.selectCompose(null, null);
|
|
97327
97605
|
flushLogsNow();
|
|
97328
97606
|
flushComposeLogsNow();
|
|
97607
|
+
flushSecondaryLogsNow();
|
|
97608
|
+
flushSecondaryComposeLogsNow();
|
|
97329
97609
|
if (itemId && !state.getImageLayers(itemId)) {
|
|
97330
97610
|
client.getImageHistory(itemId).then((layers) => {
|
|
97331
97611
|
state.setImageLayers(itemId, layers);
|
|
@@ -97336,8 +97616,12 @@ async function dashboardAction(_opts, cmd) {
|
|
|
97336
97616
|
void logManager.select(null);
|
|
97337
97617
|
void statsManager.select(null);
|
|
97338
97618
|
void composeLogManager.selectCompose(null, null);
|
|
97619
|
+
void secondaryLogManager.select(null);
|
|
97620
|
+
void secondaryComposeLogManager.selectCompose(null, null);
|
|
97339
97621
|
flushLogsNow();
|
|
97340
97622
|
flushComposeLogsNow();
|
|
97623
|
+
flushSecondaryLogsNow();
|
|
97624
|
+
flushSecondaryComposeLogsNow();
|
|
97341
97625
|
}
|
|
97342
97626
|
};
|
|
97343
97627
|
const panels = [
|
|
@@ -97347,7 +97631,7 @@ async function dashboardAction(_opts, cmd) {
|
|
|
97347
97631
|
new VolumesPanel(client, onAction, onError),
|
|
97348
97632
|
new NetworksPanel(client, onAction, onError)
|
|
97349
97633
|
];
|
|
97350
|
-
const watcher = new
|
|
97634
|
+
const watcher = new import_sidekick_docker_shared14.EventWatcher(client, {
|
|
97351
97635
|
onEvent: (event) => {
|
|
97352
97636
|
state.processEvent(event);
|
|
97353
97637
|
scheduleRender();
|
|
@@ -97392,7 +97676,7 @@ async function dashboardAction(_opts, cmd) {
|
|
|
97392
97676
|
const containersPanel = panels[0];
|
|
97393
97677
|
containersPanel.setOnExec((containerId) => {
|
|
97394
97678
|
const container = state.getMetrics().containers.find((c) => c.id === containerId);
|
|
97395
|
-
const name = container?.name ?? (0,
|
|
97679
|
+
const name = container?.name ?? (0, import_sidekick_docker_shared14.shortId)(containerId);
|
|
97396
97680
|
if (execTriggerRef.current) {
|
|
97397
97681
|
execTriggerRef.current(containerId, name);
|
|
97398
97682
|
} else {
|
|
@@ -97402,12 +97686,18 @@ async function dashboardAction(_opts, cmd) {
|
|
|
97402
97686
|
containersPanel.setOnCopyLogs((text) => {
|
|
97403
97687
|
copyToClipboard(text);
|
|
97404
97688
|
});
|
|
97689
|
+
const servicesPanel = panels[1];
|
|
97690
|
+
servicesPanel.setOnCopyLogs((text) => {
|
|
97691
|
+
copyToClipboard(text);
|
|
97692
|
+
});
|
|
97405
97693
|
let renderTimer = null;
|
|
97406
97694
|
function getEnrichedMetrics() {
|
|
97407
97695
|
const m = state.getMetrics();
|
|
97408
97696
|
m.logSeverityCounts = logSeverityCounts;
|
|
97409
97697
|
m.logSeverityTimeSeries = logManager.getSeverityTimeSeries();
|
|
97410
97698
|
m.logTemplates = logManager.getTemplates();
|
|
97699
|
+
m.secondaryLogSeverityCounts = secondaryLogSeverityCounts;
|
|
97700
|
+
m.secondaryLogSeverityTimeSeries = secondaryLogManager.getSeverityTimeSeries();
|
|
97411
97701
|
return m;
|
|
97412
97702
|
}
|
|
97413
97703
|
function scheduleRender() {
|
|
@@ -97433,6 +97723,10 @@ async function dashboardAction(_opts, cmd) {
|
|
|
97433
97723
|
logManager.dispose();
|
|
97434
97724
|
} catch {
|
|
97435
97725
|
}
|
|
97726
|
+
try {
|
|
97727
|
+
secondaryLogManager.dispose();
|
|
97728
|
+
} catch {
|
|
97729
|
+
}
|
|
97436
97730
|
try {
|
|
97437
97731
|
statsManager.dispose();
|
|
97438
97732
|
} catch {
|
|
@@ -97441,14 +97735,26 @@ async function dashboardAction(_opts, cmd) {
|
|
|
97441
97735
|
composeLogManager.dispose();
|
|
97442
97736
|
} catch {
|
|
97443
97737
|
}
|
|
97738
|
+
try {
|
|
97739
|
+
secondaryComposeLogManager.dispose();
|
|
97740
|
+
} catch {
|
|
97741
|
+
}
|
|
97444
97742
|
try {
|
|
97445
97743
|
if (logFlushTimer) clearTimeout(logFlushTimer);
|
|
97446
97744
|
} catch {
|
|
97447
97745
|
}
|
|
97746
|
+
try {
|
|
97747
|
+
if (secondaryLogFlushTimer) clearTimeout(secondaryLogFlushTimer);
|
|
97748
|
+
} catch {
|
|
97749
|
+
}
|
|
97448
97750
|
try {
|
|
97449
97751
|
if (composeLogFlushTimer) clearTimeout(composeLogFlushTimer);
|
|
97450
97752
|
} catch {
|
|
97451
97753
|
}
|
|
97754
|
+
try {
|
|
97755
|
+
if (secondaryComposeLogFlushTimer) clearTimeout(secondaryComposeLogFlushTimer);
|
|
97756
|
+
} catch {
|
|
97757
|
+
}
|
|
97452
97758
|
try {
|
|
97453
97759
|
clearInterval(refreshInterval);
|
|
97454
97760
|
} catch {
|
|
@@ -97473,9 +97779,9 @@ async function dashboardAction(_opts, cmd) {
|
|
|
97473
97779
|
}
|
|
97474
97780
|
|
|
97475
97781
|
// src/commands/ps.ts
|
|
97476
|
-
var
|
|
97782
|
+
var import_sidekick_docker_shared15 = __toESM(require_dist(), 1);
|
|
97477
97783
|
async function psAction(opts) {
|
|
97478
|
-
const client = new
|
|
97784
|
+
const client = new import_sidekick_docker_shared15.DockerClient();
|
|
97479
97785
|
const ok = await client.ping();
|
|
97480
97786
|
if (!ok) {
|
|
97481
97787
|
console.error("Error: Cannot connect to Docker daemon. Is Docker running?");
|
|
@@ -97491,7 +97797,7 @@ async function psAction(opts) {
|
|
|
97491
97797
|
console.log("-".repeat(100));
|
|
97492
97798
|
for (const c of containers) {
|
|
97493
97799
|
const row = [
|
|
97494
|
-
(0,
|
|
97800
|
+
(0, import_sidekick_docker_shared15.shortId)(c.id).padEnd(20),
|
|
97495
97801
|
`${(0, import_sidekick_docker_shared3.stateIcon)(c.state)} ${c.name}`.padEnd(20),
|
|
97496
97802
|
c.image.padEnd(20),
|
|
97497
97803
|
formatUptime(c.status).padEnd(20),
|
|
@@ -97502,9 +97808,9 @@ async function psAction(opts) {
|
|
|
97502
97808
|
}
|
|
97503
97809
|
|
|
97504
97810
|
// src/commands/logs.ts
|
|
97505
|
-
var
|
|
97811
|
+
var import_sidekick_docker_shared16 = __toESM(require_dist(), 1);
|
|
97506
97812
|
async function logsAction(container, opts) {
|
|
97507
|
-
const client = new
|
|
97813
|
+
const client = new import_sidekick_docker_shared16.DockerClient();
|
|
97508
97814
|
const ok = await client.ping();
|
|
97509
97815
|
if (!ok) {
|
|
97510
97816
|
console.error("Error: Cannot connect to Docker daemon. Is Docker running?");
|
|
@@ -97515,13 +97821,13 @@ async function logsAction(container, opts) {
|
|
|
97515
97821
|
follow: opts.follow ?? true,
|
|
97516
97822
|
tail: parseInt(opts.tail || "100", 10)
|
|
97517
97823
|
})) {
|
|
97518
|
-
const ts = entry.timestamp ? (0,
|
|
97824
|
+
const ts = entry.timestamp ? (0, import_sidekick_docker_shared16.formatTimestampTime)(entry.timestamp) : "";
|
|
97519
97825
|
const prefix = entry.stream === "stderr" ? "\x1B[31m" : "";
|
|
97520
97826
|
const reset = entry.stream === "stderr" ? "\x1B[0m" : "";
|
|
97521
97827
|
console.log(`${prefix}${ts} ${entry.message}${reset}`);
|
|
97522
97828
|
}
|
|
97523
97829
|
} catch (err) {
|
|
97524
|
-
const msg = (0,
|
|
97830
|
+
const msg = (0, import_sidekick_docker_shared16.errorMessage)(err);
|
|
97525
97831
|
if (msg.includes("no such container") || msg.includes("No such container")) {
|
|
97526
97832
|
console.error(`Error: Container "${container}" not found.`);
|
|
97527
97833
|
} else {
|
|
@@ -97533,7 +97839,7 @@ async function logsAction(container, opts) {
|
|
|
97533
97839
|
|
|
97534
97840
|
// src/cli.ts
|
|
97535
97841
|
var program2 = new Command();
|
|
97536
|
-
program2.name("sidekick-docker").description("Docker management TUI dashboard").version("0.2.
|
|
97842
|
+
program2.name("sidekick-docker").description("Docker management TUI dashboard").version("0.2.3").option("--socket <path>", "Docker socket path").action(async (_opts, cmd) => {
|
|
97537
97843
|
await dashboardAction(_opts, cmd);
|
|
97538
97844
|
});
|
|
97539
97845
|
program2.command("ps").description("List containers").option("-a, --all", "Show all containers (default: running only)", false).action(async (opts) => {
|