sidekick-docker 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/sidekick-docker.mjs +92 -49
- package/package.json +1 -1
package/dist/sidekick-docker.mjs
CHANGED
|
@@ -94732,9 +94732,7 @@ var ContainersPanel = class {
|
|
|
94732
94732
|
if (c.state !== "running") return "Container is not running.";
|
|
94733
94733
|
const latest = metrics.statsCollector.getLatest(c.id);
|
|
94734
94734
|
if (!latest) {
|
|
94735
|
-
|
|
94736
|
-
const idx = Math.floor(Date.now() / 200) % frames.length;
|
|
94737
|
-
return `${frames[idx]} Loading stats...`;
|
|
94735
|
+
return "Loading stats...";
|
|
94738
94736
|
}
|
|
94739
94737
|
const cpuSeries = metrics.statsCollector.getCpuSeries(c.id);
|
|
94740
94738
|
const memSeries = metrics.statsCollector.getMemorySeries(c.id);
|
|
@@ -95533,7 +95531,6 @@ var LogStreamManager = class extends BaseStreamManager {
|
|
|
95533
95531
|
var StatsStreamManager = class extends BaseStreamManager {
|
|
95534
95532
|
client;
|
|
95535
95533
|
collector;
|
|
95536
|
-
loadingInterval = null;
|
|
95537
95534
|
streamLabel = "stats";
|
|
95538
95535
|
constructor(client, collector, onChange) {
|
|
95539
95536
|
super(onChange);
|
|
@@ -95557,21 +95554,11 @@ var StatsStreamManager = class extends BaseStreamManager {
|
|
|
95557
95554
|
}
|
|
95558
95555
|
processItem(id, stats) {
|
|
95559
95556
|
this.collector.push(id, stats);
|
|
95560
|
-
this.clearLoadingInterval();
|
|
95561
95557
|
}
|
|
95562
95558
|
onClear() {
|
|
95563
95559
|
}
|
|
95564
95560
|
onBeforeStream() {
|
|
95565
|
-
this.
|
|
95566
|
-
}
|
|
95567
|
-
onStop() {
|
|
95568
|
-
this.clearLoadingInterval();
|
|
95569
|
-
}
|
|
95570
|
-
clearLoadingInterval() {
|
|
95571
|
-
if (this.loadingInterval) {
|
|
95572
|
-
clearInterval(this.loadingInterval);
|
|
95573
|
-
this.loadingInterval = null;
|
|
95574
|
-
}
|
|
95561
|
+
this.onChange();
|
|
95575
95562
|
}
|
|
95576
95563
|
getCollector() {
|
|
95577
95564
|
return this.collector;
|
|
@@ -96229,8 +96216,7 @@ function DetailTabBar({ tabs, activeIndex }) {
|
|
|
96229
96216
|
// src/dashboard/ink/DetailPane.tsx
|
|
96230
96217
|
await init_build2();
|
|
96231
96218
|
var import_jsx_runtime4 = __toESM(require_jsx_runtime(), 1);
|
|
96232
|
-
function DetailPane({
|
|
96233
|
-
const lines = content.split("\n");
|
|
96219
|
+
function DetailPane({ lines, scrollOffset, viewportHeight, focused }) {
|
|
96234
96220
|
const visibleLines = lines.slice(scrollOffset, scrollOffset + viewportHeight);
|
|
96235
96221
|
const hasScrollUp = scrollOffset > 0;
|
|
96236
96222
|
const hasScrollDown = scrollOffset + viewportHeight < lines.length;
|
|
@@ -96259,7 +96245,7 @@ var SEP2 = "\u2502";
|
|
|
96259
96245
|
function StatusBar({ daemonConnected, focusTarget, panelActionHints, filterString, containerCount, runningCount, version: version2, matchCount, totalCount, lastRefresh, contextHint }) {
|
|
96260
96246
|
const [, setTick] = (0, import_react32.useState)(0);
|
|
96261
96247
|
(0, import_react32.useEffect)(() => {
|
|
96262
|
-
const timer = setInterval(() => setTick((t) => t + 1),
|
|
96248
|
+
const timer = setInterval(() => setTick((t) => t + 1), 3e4);
|
|
96263
96249
|
return () => clearInterval(timer);
|
|
96264
96250
|
}, []);
|
|
96265
96251
|
const ago = lastRefresh ? formatAgo(lastRefresh) : null;
|
|
@@ -96885,7 +96871,7 @@ var initialState = {
|
|
|
96885
96871
|
sortReversed: false,
|
|
96886
96872
|
sortMenuIndex: 0
|
|
96887
96873
|
};
|
|
96888
|
-
function Dashboard({ panels, metrics,
|
|
96874
|
+
function Dashboard({ panels, metrics, onViewStateChange, execTriggerRef, onExecFallback }) {
|
|
96889
96875
|
const [state, dispatch] = (0, import_react36.useReducer)(reducer, initialState);
|
|
96890
96876
|
const { columns, rows } = useTerminalSize();
|
|
96891
96877
|
const toastIdRef = (0, import_react36.useRef)(0);
|
|
@@ -97047,11 +97033,16 @@ function Dashboard({ panels, metrics, onSelectionChange, execTriggerRef, onExecF
|
|
|
97047
97033
|
}
|
|
97048
97034
|
}, [state.selectedItemIndex]);
|
|
97049
97035
|
const selectedItem = currentItems[clampedSelection];
|
|
97050
|
-
(0, import_react36.useEffect)(() => {
|
|
97051
|
-
onSelectionChange?.(panel.id, selectedItem?.id ?? null);
|
|
97052
|
-
}, [panel.id, selectedItem?.id]);
|
|
97053
97036
|
const detailTabs = panel.detailTabs;
|
|
97054
97037
|
const tabIdx = Math.min(state.detailTabIndex, detailTabs.length - 1);
|
|
97038
|
+
(0, import_react36.useEffect)(() => {
|
|
97039
|
+
onViewStateChange?.({
|
|
97040
|
+
panelId: panel.id,
|
|
97041
|
+
itemId: selectedItem?.id ?? null,
|
|
97042
|
+
detailTabIndex: tabIdx,
|
|
97043
|
+
sortField: state.sortField
|
|
97044
|
+
});
|
|
97045
|
+
}, [panel.id, selectedItem?.id, tabIdx, state.sortField]);
|
|
97055
97046
|
const enrichedMetrics = {
|
|
97056
97047
|
...metrics,
|
|
97057
97048
|
logFilterString: state.logFilterString,
|
|
@@ -97160,7 +97151,7 @@ function Dashboard({ panels, metrics, onSelectionChange, execTriggerRef, onExecF
|
|
|
97160
97151
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
97161
97152
|
DetailPane,
|
|
97162
97153
|
{
|
|
97163
|
-
|
|
97154
|
+
lines: detailLines,
|
|
97164
97155
|
scrollOffset: state.detailScrollOffset,
|
|
97165
97156
|
viewportHeight: detailViewportHeight,
|
|
97166
97157
|
focused: state.focusTarget === "detail"
|
|
@@ -97168,8 +97159,8 @@ function Dashboard({ panels, metrics, onSelectionChange, execTriggerRef, onExecF
|
|
|
97168
97159
|
)
|
|
97169
97160
|
] })
|
|
97170
97161
|
] }),
|
|
97171
|
-
state.overlay === "help" && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(HelpOverlay, { panels, activePanelIndex: state.activePanelIndex, version: "0.2.
|
|
97172
|
-
state.overlay === "version" && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(VersionOverlay, { version: "0.2.
|
|
97162
|
+
state.overlay === "help" && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(HelpOverlay, { panels, activePanelIndex: state.activePanelIndex, version: "0.2.1" }),
|
|
97163
|
+
state.overlay === "version" && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(VersionOverlay, { version: "0.2.1" }),
|
|
97173
97164
|
state.overlay === "exec" && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
97174
97165
|
ExecOverlay,
|
|
97175
97166
|
{
|
|
@@ -97186,7 +97177,7 @@ function Dashboard({ panels, metrics, onSelectionChange, execTriggerRef, onExecF
|
|
|
97186
97177
|
filterString: state.filterString,
|
|
97187
97178
|
containerCount: metrics.containers.length,
|
|
97188
97179
|
runningCount,
|
|
97189
|
-
version: "0.2.
|
|
97180
|
+
version: "0.2.1",
|
|
97190
97181
|
matchCount: state.filterString ? currentItems.length : void 0,
|
|
97191
97182
|
totalCount: state.filterString ? totalItemCount : void 0,
|
|
97192
97183
|
lastRefresh: metrics.lastRefresh,
|
|
@@ -97247,27 +97238,61 @@ async function dashboardAction(_opts, cmd) {
|
|
|
97247
97238
|
const onError = (msg) => {
|
|
97248
97239
|
console.debug("panel action failed:", msg);
|
|
97249
97240
|
};
|
|
97241
|
+
let logFlushTimer = null;
|
|
97242
|
+
let composeLogFlushTimer = null;
|
|
97250
97243
|
const logManager = new LogStreamManager(client, () => {
|
|
97244
|
+
if (logFlushTimer) return;
|
|
97245
|
+
logFlushTimer = setTimeout(() => {
|
|
97246
|
+
logFlushTimer = null;
|
|
97247
|
+
state.setSelectedLogs(logManager.getLogs());
|
|
97248
|
+
logSeverityCounts = logManager.getSeverityCounts();
|
|
97249
|
+
scheduleRender();
|
|
97250
|
+
}, 100);
|
|
97251
|
+
});
|
|
97252
|
+
const flushLogsNow = () => {
|
|
97253
|
+
if (logFlushTimer) {
|
|
97254
|
+
clearTimeout(logFlushTimer);
|
|
97255
|
+
logFlushTimer = null;
|
|
97256
|
+
}
|
|
97251
97257
|
state.setSelectedLogs(logManager.getLogs());
|
|
97252
97258
|
logSeverityCounts = logManager.getSeverityCounts();
|
|
97253
97259
|
scheduleRender();
|
|
97254
|
-
}
|
|
97260
|
+
};
|
|
97255
97261
|
let logSeverityCounts = logManager.getSeverityCounts();
|
|
97256
97262
|
const statsManager = new StatsStreamManager(client, state.getStatsCollector(), () => {
|
|
97257
97263
|
scheduleRender();
|
|
97258
97264
|
});
|
|
97259
97265
|
const composeLogManager = new ComposeLogStreamManager(composeClient, () => {
|
|
97266
|
+
if (composeLogFlushTimer) return;
|
|
97267
|
+
composeLogFlushTimer = setTimeout(() => {
|
|
97268
|
+
composeLogFlushTimer = null;
|
|
97269
|
+
state.clearComposeLogs();
|
|
97270
|
+
for (const entry of composeLogManager.getLogs()) {
|
|
97271
|
+
state.appendComposeLog(entry);
|
|
97272
|
+
}
|
|
97273
|
+
scheduleRender();
|
|
97274
|
+
}, 100);
|
|
97275
|
+
});
|
|
97276
|
+
const flushComposeLogsNow = () => {
|
|
97277
|
+
if (composeLogFlushTimer) {
|
|
97278
|
+
clearTimeout(composeLogFlushTimer);
|
|
97279
|
+
composeLogFlushTimer = null;
|
|
97280
|
+
}
|
|
97260
97281
|
state.clearComposeLogs();
|
|
97261
97282
|
for (const entry of composeLogManager.getLogs()) {
|
|
97262
97283
|
state.appendComposeLog(entry);
|
|
97263
97284
|
}
|
|
97264
97285
|
scheduleRender();
|
|
97265
|
-
}
|
|
97266
|
-
const
|
|
97286
|
+
};
|
|
97287
|
+
const onViewStateChange = (viewState) => {
|
|
97288
|
+
const { panelId, itemId, detailTabIndex, sortField } = viewState;
|
|
97289
|
+
const wantsLiveStats = sortField === "cpu" || sortField === "mem" || sortField === "net" || sortField === "io" || sortField === "pids";
|
|
97267
97290
|
if (panelId === "containers") {
|
|
97268
|
-
logManager.select(itemId);
|
|
97269
|
-
statsManager.select(itemId);
|
|
97270
|
-
composeLogManager.selectCompose(null, null);
|
|
97291
|
+
void logManager.select(detailTabIndex === 0 ? itemId : null);
|
|
97292
|
+
void statsManager.select(itemId && (detailTabIndex === 1 || wantsLiveStats) ? itemId : null);
|
|
97293
|
+
void composeLogManager.selectCompose(null, null);
|
|
97294
|
+
flushLogsNow();
|
|
97295
|
+
flushComposeLogsNow();
|
|
97271
97296
|
if (itemId && !state.getInspectedEnv(itemId)) {
|
|
97272
97297
|
client.getContainerEnv(itemId).then((env3) => {
|
|
97273
97298
|
state.setInspectedEnv(itemId, env3);
|
|
@@ -97281,18 +97306,26 @@ async function dashboardAction(_opts, cmd) {
|
|
|
97281
97306
|
}).catch((e) => console.debug("getContainerChanges failed:", e));
|
|
97282
97307
|
}
|
|
97283
97308
|
} else if (panelId === "services" && itemId) {
|
|
97284
|
-
logManager.select(null);
|
|
97285
|
-
statsManager.select(null);
|
|
97286
|
-
|
|
97287
|
-
|
|
97288
|
-
|
|
97289
|
-
|
|
97290
|
-
|
|
97309
|
+
void logManager.select(null);
|
|
97310
|
+
void statsManager.select(null);
|
|
97311
|
+
if (detailTabIndex === 1) {
|
|
97312
|
+
const parts = itemId.split(":");
|
|
97313
|
+
if (parts[0] === "project") {
|
|
97314
|
+
void composeLogManager.selectCompose(parts.slice(1).join(":"), null);
|
|
97315
|
+
} else if (parts[0] === "service") {
|
|
97316
|
+
void composeLogManager.selectCompose(parts[1], parts.slice(2).join(":"));
|
|
97317
|
+
}
|
|
97318
|
+
} else {
|
|
97319
|
+
void composeLogManager.selectCompose(null, null);
|
|
97291
97320
|
}
|
|
97321
|
+
flushLogsNow();
|
|
97322
|
+
flushComposeLogsNow();
|
|
97292
97323
|
} else if (panelId === "images") {
|
|
97293
|
-
logManager.select(null);
|
|
97294
|
-
statsManager.select(null);
|
|
97295
|
-
composeLogManager.selectCompose(null, null);
|
|
97324
|
+
void logManager.select(null);
|
|
97325
|
+
void statsManager.select(null);
|
|
97326
|
+
void composeLogManager.selectCompose(null, null);
|
|
97327
|
+
flushLogsNow();
|
|
97328
|
+
flushComposeLogsNow();
|
|
97296
97329
|
if (itemId && !state.getImageLayers(itemId)) {
|
|
97297
97330
|
client.getImageHistory(itemId).then((layers) => {
|
|
97298
97331
|
state.setImageLayers(itemId, layers);
|
|
@@ -97300,9 +97333,11 @@ async function dashboardAction(_opts, cmd) {
|
|
|
97300
97333
|
}).catch((e) => console.debug("getImageHistory failed:", e));
|
|
97301
97334
|
}
|
|
97302
97335
|
} else {
|
|
97303
|
-
logManager.select(null);
|
|
97304
|
-
statsManager.select(null);
|
|
97305
|
-
composeLogManager.selectCompose(null, null);
|
|
97336
|
+
void logManager.select(null);
|
|
97337
|
+
void statsManager.select(null);
|
|
97338
|
+
void composeLogManager.selectCompose(null, null);
|
|
97339
|
+
flushLogsNow();
|
|
97340
|
+
flushComposeLogsNow();
|
|
97306
97341
|
}
|
|
97307
97342
|
};
|
|
97308
97343
|
const panels = [
|
|
@@ -97337,7 +97372,7 @@ async function dashboardAction(_opts, cmd) {
|
|
|
97337
97372
|
import_react37.default.createElement(Dashboard, {
|
|
97338
97373
|
panels,
|
|
97339
97374
|
metrics: getEnrichedMetrics(),
|
|
97340
|
-
|
|
97375
|
+
onViewStateChange,
|
|
97341
97376
|
execTriggerRef,
|
|
97342
97377
|
onExecFallback
|
|
97343
97378
|
})
|
|
@@ -97349,7 +97384,7 @@ async function dashboardAction(_opts, cmd) {
|
|
|
97349
97384
|
import_react37.default.createElement(Dashboard, {
|
|
97350
97385
|
panels,
|
|
97351
97386
|
metrics: getEnrichedMetrics(),
|
|
97352
|
-
|
|
97387
|
+
onViewStateChange,
|
|
97353
97388
|
execTriggerRef,
|
|
97354
97389
|
onExecFallback
|
|
97355
97390
|
})
|
|
@@ -97383,7 +97418,7 @@ async function dashboardAction(_opts, cmd) {
|
|
|
97383
97418
|
import_react37.default.createElement(Dashboard, {
|
|
97384
97419
|
panels,
|
|
97385
97420
|
metrics: getEnrichedMetrics(),
|
|
97386
|
-
|
|
97421
|
+
onViewStateChange,
|
|
97387
97422
|
execTriggerRef,
|
|
97388
97423
|
onExecFallback
|
|
97389
97424
|
})
|
|
@@ -97406,6 +97441,14 @@ async function dashboardAction(_opts, cmd) {
|
|
|
97406
97441
|
composeLogManager.dispose();
|
|
97407
97442
|
} catch {
|
|
97408
97443
|
}
|
|
97444
|
+
try {
|
|
97445
|
+
if (logFlushTimer) clearTimeout(logFlushTimer);
|
|
97446
|
+
} catch {
|
|
97447
|
+
}
|
|
97448
|
+
try {
|
|
97449
|
+
if (composeLogFlushTimer) clearTimeout(composeLogFlushTimer);
|
|
97450
|
+
} catch {
|
|
97451
|
+
}
|
|
97409
97452
|
try {
|
|
97410
97453
|
clearInterval(refreshInterval);
|
|
97411
97454
|
} catch {
|
|
@@ -97490,7 +97533,7 @@ async function logsAction(container, opts) {
|
|
|
97490
97533
|
|
|
97491
97534
|
// src/cli.ts
|
|
97492
97535
|
var program2 = new Command();
|
|
97493
|
-
program2.name("sidekick-docker").description("Docker management TUI dashboard").version("0.2.
|
|
97536
|
+
program2.name("sidekick-docker").description("Docker management TUI dashboard").version("0.2.1").option("--socket <path>", "Docker socket path").action(async (_opts, cmd) => {
|
|
97494
97537
|
await dashboardAction(_opts, cmd);
|
|
97495
97538
|
});
|
|
97496
97539
|
program2.command("ps").description("List containers").option("-a, --all", "Show all containers (default: running only)", false).action(async (opts) => {
|