sidekick-docker 0.2.3 → 0.2.5
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 +207 -91
- package/package.json +1 -1
package/dist/sidekick-docker.mjs
CHANGED
|
@@ -55711,7 +55711,7 @@ var require_DockerClient = __commonJS({
|
|
|
55711
55711
|
const validated = schemas_1.ContainerInspectEnvSchema.parse(info);
|
|
55712
55712
|
return validated.Config.Env ?? [];
|
|
55713
55713
|
}
|
|
55714
|
-
async *streamLogs(id, opts = {}) {
|
|
55714
|
+
async *streamLogs(id, opts = {}, signal) {
|
|
55715
55715
|
const container = this.docker.getContainer(id);
|
|
55716
55716
|
const logOpts = {
|
|
55717
55717
|
follow: true,
|
|
@@ -55732,32 +55732,42 @@ var require_DockerClient = __commonJS({
|
|
|
55732
55732
|
return;
|
|
55733
55733
|
}
|
|
55734
55734
|
const readable = stream;
|
|
55735
|
+
const destroy = () => readable.destroy?.();
|
|
55736
|
+
if (signal) {
|
|
55737
|
+
signal.addEventListener("abort", destroy, { once: true });
|
|
55738
|
+
}
|
|
55735
55739
|
const buffer = [];
|
|
55736
|
-
|
|
55737
|
-
|
|
55738
|
-
|
|
55739
|
-
const combined = Buffer.concat(buffer);
|
|
55740
|
-
buffer.length = 0;
|
|
55741
|
-
let offset = 0;
|
|
55742
|
-
while (offset + 8 <= combined.length) {
|
|
55743
|
-
const streamType = combined[offset];
|
|
55744
|
-
const size = combined.readUInt32BE(offset + 4);
|
|
55745
|
-
if (offset + 8 + size > combined.length) {
|
|
55746
|
-
buffer.push(combined.subarray(offset));
|
|
55740
|
+
try {
|
|
55741
|
+
for await (const chunk of readable) {
|
|
55742
|
+
if (signal?.aborted)
|
|
55747
55743
|
break;
|
|
55748
|
-
|
|
55749
|
-
|
|
55750
|
-
const
|
|
55751
|
-
|
|
55752
|
-
|
|
55753
|
-
|
|
55744
|
+
const data = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
55745
|
+
buffer.push(data);
|
|
55746
|
+
const combined = Buffer.concat(buffer);
|
|
55747
|
+
buffer.length = 0;
|
|
55748
|
+
let offset = 0;
|
|
55749
|
+
while (offset + 8 <= combined.length) {
|
|
55750
|
+
const streamType = combined[offset];
|
|
55751
|
+
const size = combined.readUInt32BE(offset + 4);
|
|
55752
|
+
if (offset + 8 + size > combined.length) {
|
|
55753
|
+
buffer.push(combined.subarray(offset));
|
|
55754
|
+
break;
|
|
55754
55755
|
}
|
|
55756
|
+
const payload = combined.subarray(offset + 8, offset + 8 + size).toString("utf8");
|
|
55757
|
+
const streamName = streamType === 2 ? "stderr" : "stdout";
|
|
55758
|
+
for (const line of payload.split("\n")) {
|
|
55759
|
+
if (line.trim()) {
|
|
55760
|
+
yield parseLogLine(line, streamName);
|
|
55761
|
+
}
|
|
55762
|
+
}
|
|
55763
|
+
offset += 8 + size;
|
|
55764
|
+
}
|
|
55765
|
+
if (offset < combined.length && buffer.length === 0) {
|
|
55766
|
+
buffer.push(combined.subarray(offset));
|
|
55755
55767
|
}
|
|
55756
|
-
offset += 8 + size;
|
|
55757
|
-
}
|
|
55758
|
-
if (offset < combined.length && buffer.length === 0) {
|
|
55759
|
-
buffer.push(combined.subarray(offset));
|
|
55760
55768
|
}
|
|
55769
|
+
} finally {
|
|
55770
|
+
destroy();
|
|
55761
55771
|
}
|
|
55762
55772
|
}
|
|
55763
55773
|
parseStats(validated, prevCpu, prevSystem) {
|
|
@@ -55813,7 +55823,7 @@ var require_DockerClient = __commonJS({
|
|
|
55813
55823
|
systemTotal: systemUsage
|
|
55814
55824
|
};
|
|
55815
55825
|
}
|
|
55816
|
-
async *streamStats(id) {
|
|
55826
|
+
async *streamStats(id, signal) {
|
|
55817
55827
|
const container = this.docker.getContainer(id);
|
|
55818
55828
|
let prevCpu = 0;
|
|
55819
55829
|
let prevSystem = 0;
|
|
@@ -55826,21 +55836,33 @@ var require_DockerClient = __commonJS({
|
|
|
55826
55836
|
yield first;
|
|
55827
55837
|
} catch {
|
|
55828
55838
|
}
|
|
55839
|
+
if (signal?.aborted)
|
|
55840
|
+
return;
|
|
55829
55841
|
const stream = await container.stats({ stream: true });
|
|
55830
|
-
|
|
55831
|
-
|
|
55832
|
-
|
|
55833
|
-
|
|
55834
|
-
|
|
55835
|
-
|
|
55836
|
-
|
|
55837
|
-
|
|
55838
|
-
|
|
55839
|
-
|
|
55840
|
-
|
|
55841
|
-
|
|
55842
|
+
const destroy = () => stream.destroy?.();
|
|
55843
|
+
if (signal) {
|
|
55844
|
+
signal.addEventListener("abort", destroy, { once: true });
|
|
55845
|
+
}
|
|
55846
|
+
try {
|
|
55847
|
+
for await (const chunk of stream) {
|
|
55848
|
+
if (signal?.aborted)
|
|
55849
|
+
break;
|
|
55850
|
+
const lines = chunk.toString("utf8").split("\n").filter(Boolean);
|
|
55851
|
+
for (const line of lines) {
|
|
55852
|
+
try {
|
|
55853
|
+
const raw = JSON.parse(line);
|
|
55854
|
+
const validated = schemas_1.DockerStatsRawSchema.parse(raw);
|
|
55855
|
+
const { stats, cpuTotal, systemTotal } = this.parseStats(validated, prevCpu, prevSystem);
|
|
55856
|
+
prevCpu = cpuTotal;
|
|
55857
|
+
prevSystem = systemTotal;
|
|
55858
|
+
yield stats;
|
|
55859
|
+
} catch {
|
|
55860
|
+
continue;
|
|
55861
|
+
}
|
|
55842
55862
|
}
|
|
55843
55863
|
}
|
|
55864
|
+
} finally {
|
|
55865
|
+
destroy();
|
|
55844
55866
|
}
|
|
55845
55867
|
}
|
|
55846
55868
|
async listImages(all = false) {
|
|
@@ -56140,7 +56162,7 @@ var require_ComposeClient = __commonJS({
|
|
|
56140
56162
|
async ps(project) {
|
|
56141
56163
|
return this.exec(["-p", project, "ps", "--format", "json"]);
|
|
56142
56164
|
}
|
|
56143
|
-
async *streamLogs(project, service, tail = 100) {
|
|
56165
|
+
async *streamLogs(project, service, tail = 100, signal) {
|
|
56144
56166
|
const args = ["-p", project, "logs", "--follow", "--tail", String(tail), "--timestamps"];
|
|
56145
56167
|
if (service)
|
|
56146
56168
|
args.push(service);
|
|
@@ -56179,6 +56201,14 @@ var require_ComposeClient = __commonJS({
|
|
|
56179
56201
|
entries.push(entry);
|
|
56180
56202
|
resolve?.();
|
|
56181
56203
|
};
|
|
56204
|
+
const kill = () => {
|
|
56205
|
+
done = true;
|
|
56206
|
+
resolve?.();
|
|
56207
|
+
proc.kill();
|
|
56208
|
+
};
|
|
56209
|
+
if (signal) {
|
|
56210
|
+
signal.addEventListener("abort", kill, { once: true });
|
|
56211
|
+
}
|
|
56182
56212
|
proc.stdout.on("data", (data) => {
|
|
56183
56213
|
stdoutBuffer += data.toString();
|
|
56184
56214
|
const lines = stdoutBuffer.split("\n");
|
|
@@ -56220,6 +56250,9 @@ var require_ComposeClient = __commonJS({
|
|
|
56220
56250
|
}
|
|
56221
56251
|
}
|
|
56222
56252
|
} finally {
|
|
56253
|
+
proc.stdout.removeAllListeners();
|
|
56254
|
+
proc.stderr.removeAllListeners();
|
|
56255
|
+
proc.removeAllListeners();
|
|
56223
56256
|
proc.kill();
|
|
56224
56257
|
}
|
|
56225
56258
|
}
|
|
@@ -56399,6 +56432,14 @@ var require_StatsCollector = __commonJS({
|
|
|
56399
56432
|
remove(containerId) {
|
|
56400
56433
|
this.histories.delete(containerId);
|
|
56401
56434
|
}
|
|
56435
|
+
/** Remove history entries for containers not in the active set. */
|
|
56436
|
+
prune(activeContainerIds) {
|
|
56437
|
+
for (const id of this.histories.keys()) {
|
|
56438
|
+
if (!activeContainerIds.has(id)) {
|
|
56439
|
+
this.histories.delete(id);
|
|
56440
|
+
}
|
|
56441
|
+
}
|
|
56442
|
+
}
|
|
56402
56443
|
clear() {
|
|
56403
56444
|
this.histories.clear();
|
|
56404
56445
|
}
|
|
@@ -56801,10 +56842,17 @@ var require_LogTemplateEngine = __commonJS({
|
|
|
56801
56842
|
function isVariable(token) {
|
|
56802
56843
|
return VARIABLE_PATTERNS.some((p) => p.test(token));
|
|
56803
56844
|
}
|
|
56845
|
+
var DEFAULT_MAX_GROUPS = 500;
|
|
56804
56846
|
var LogTemplateEngine2 = class {
|
|
56805
56847
|
// Group templates by token count for efficient lookup
|
|
56806
56848
|
groups = /* @__PURE__ */ new Map();
|
|
56807
56849
|
totalLines = 0;
|
|
56850
|
+
groupCount = 0;
|
|
56851
|
+
droppedGroups = 0;
|
|
56852
|
+
maxGroups;
|
|
56853
|
+
constructor(maxGroups = DEFAULT_MAX_GROUPS) {
|
|
56854
|
+
this.maxGroups = maxGroups;
|
|
56855
|
+
}
|
|
56808
56856
|
/**
|
|
56809
56857
|
* Process a log line and update templates.
|
|
56810
56858
|
*/
|
|
@@ -56815,7 +56863,12 @@ var require_LogTemplateEngine = __commonJS({
|
|
|
56815
56863
|
return;
|
|
56816
56864
|
const groups = this.groups.get(tokens.length);
|
|
56817
56865
|
if (!groups) {
|
|
56866
|
+
if (this.groupCount >= this.maxGroups) {
|
|
56867
|
+
this.droppedGroups++;
|
|
56868
|
+
return;
|
|
56869
|
+
}
|
|
56818
56870
|
this.groups.set(tokens.length, [{ tokens: tokens.map((t) => isVariable(t) ? "<*>" : t), count: 1 }]);
|
|
56871
|
+
this.groupCount++;
|
|
56819
56872
|
return;
|
|
56820
56873
|
}
|
|
56821
56874
|
let bestMatch = null;
|
|
@@ -56840,8 +56893,11 @@ var require_LogTemplateEngine = __commonJS({
|
|
|
56840
56893
|
bestMatch.tokens[i] = "<*>";
|
|
56841
56894
|
}
|
|
56842
56895
|
}
|
|
56843
|
-
} else {
|
|
56896
|
+
} else if (this.groupCount < this.maxGroups) {
|
|
56844
56897
|
groups.push({ tokens: tokens.map((t) => isVariable(t) ? "<*>" : t), count: 1 });
|
|
56898
|
+
this.groupCount++;
|
|
56899
|
+
} else {
|
|
56900
|
+
this.droppedGroups++;
|
|
56845
56901
|
}
|
|
56846
56902
|
}
|
|
56847
56903
|
/**
|
|
@@ -56864,9 +56920,18 @@ var require_LogTemplateEngine = __commonJS({
|
|
|
56864
56920
|
getTotalLines() {
|
|
56865
56921
|
return this.totalLines;
|
|
56866
56922
|
}
|
|
56923
|
+
getDiagnostics() {
|
|
56924
|
+
return {
|
|
56925
|
+
groupCount: this.groupCount,
|
|
56926
|
+
droppedGroups: this.droppedGroups,
|
|
56927
|
+
totalLines: this.totalLines
|
|
56928
|
+
};
|
|
56929
|
+
}
|
|
56867
56930
|
reset() {
|
|
56868
56931
|
this.groups.clear();
|
|
56869
56932
|
this.totalLines = 0;
|
|
56933
|
+
this.groupCount = 0;
|
|
56934
|
+
this.droppedGroups = 0;
|
|
56870
56935
|
}
|
|
56871
56936
|
};
|
|
56872
56937
|
exports2.LogTemplateEngine = LogTemplateEngine2;
|
|
@@ -94320,6 +94385,19 @@ var DockerState = class {
|
|
|
94320
94385
|
this.composeProjects = this.composeDetector.detect(containers, fileConfig);
|
|
94321
94386
|
this.lastRefresh = /* @__PURE__ */ new Date();
|
|
94322
94387
|
this.daemonConnected = true;
|
|
94388
|
+
const currentContainerIds = new Set(containers.map((c) => c.id));
|
|
94389
|
+
for (const id of this.inspectedEnv.keys()) {
|
|
94390
|
+
if (!currentContainerIds.has(id)) this.inspectedEnv.delete(id);
|
|
94391
|
+
}
|
|
94392
|
+
for (const id of this.containerChanges.keys()) {
|
|
94393
|
+
if (!currentContainerIds.has(id)) this.containerChanges.delete(id);
|
|
94394
|
+
}
|
|
94395
|
+
const currentImageIds = new Set(images.map((i) => i.id));
|
|
94396
|
+
for (const id of this.imageLayers.keys()) {
|
|
94397
|
+
if (!currentImageIds.has(id)) this.imageLayers.delete(id);
|
|
94398
|
+
}
|
|
94399
|
+
const runningIds = new Set(containers.filter((c) => c.state === "running").map((c) => c.id));
|
|
94400
|
+
this.statsCollector.prune(runningIds);
|
|
94323
94401
|
} catch {
|
|
94324
94402
|
this.daemonConnected = false;
|
|
94325
94403
|
}
|
|
@@ -94369,6 +94447,8 @@ var DockerState = class {
|
|
|
94369
94447
|
case "destroy":
|
|
94370
94448
|
this.containers = this.containers.filter((c) => c.id !== resourceId);
|
|
94371
94449
|
this.statsCollector.remove(resourceId);
|
|
94450
|
+
this.inspectedEnv.delete(resourceId);
|
|
94451
|
+
this.containerChanges.delete(resourceId);
|
|
94372
94452
|
break;
|
|
94373
94453
|
case "create":
|
|
94374
94454
|
this.refresh().catch((e) => console.debug("refresh failed:", e));
|
|
@@ -94437,19 +94517,19 @@ var DockerState = class {
|
|
|
94437
94517
|
}
|
|
94438
94518
|
getMetrics() {
|
|
94439
94519
|
return {
|
|
94440
|
-
containers:
|
|
94441
|
-
images:
|
|
94442
|
-
volumes:
|
|
94443
|
-
networks:
|
|
94444
|
-
composeProjects:
|
|
94520
|
+
containers: this.containers,
|
|
94521
|
+
images: this.images,
|
|
94522
|
+
volumes: this.volumes,
|
|
94523
|
+
networks: this.networks,
|
|
94524
|
+
composeProjects: this.composeProjects,
|
|
94445
94525
|
statsCollector: this.statsCollector,
|
|
94446
94526
|
inspectedEnv: this.inspectedEnv,
|
|
94447
94527
|
containerChanges: this.containerChanges,
|
|
94448
94528
|
imageLayers: this.imageLayers,
|
|
94449
|
-
selectedContainerLogs:
|
|
94450
|
-
selectedComposeLogs:
|
|
94451
|
-
secondaryContainerLogs:
|
|
94452
|
-
secondaryComposeLogs:
|
|
94529
|
+
selectedContainerLogs: this.selectedLogs,
|
|
94530
|
+
selectedComposeLogs: this.selectedComposeLogs,
|
|
94531
|
+
secondaryContainerLogs: this.secondaryLogs,
|
|
94532
|
+
secondaryComposeLogs: this.secondaryComposeLogs,
|
|
94453
94533
|
lastRefresh: this.lastRefresh,
|
|
94454
94534
|
daemonConnected: this.daemonConnected,
|
|
94455
94535
|
logFilterString: "",
|
|
@@ -94593,17 +94673,27 @@ function colorizeTokens(message) {
|
|
|
94593
94673
|
return colorFn ? colorFn(t.text) : t.text;
|
|
94594
94674
|
}).join("");
|
|
94595
94675
|
}
|
|
94676
|
+
var colorizedCache = /* @__PURE__ */ new WeakMap();
|
|
94596
94677
|
function colorizeLogEntry(entry, filterMatches) {
|
|
94678
|
+
if (!filterMatches) {
|
|
94679
|
+
const cached = colorizedCache.get(entry);
|
|
94680
|
+
if (cached !== void 0) return cached;
|
|
94681
|
+
}
|
|
94597
94682
|
const ts = entry.timestamp ? (0, import_sidekick_docker_shared2.formatTimestampTime)(entry.timestamp) : "";
|
|
94598
94683
|
const tsColored = ts ? ansi.dim(ansi.gray(ts)) + " " : "";
|
|
94684
|
+
let result;
|
|
94599
94685
|
if (entry.stream === "stderr") {
|
|
94600
94686
|
const msg = filterMatches ? highlightMatches(entry.message, filterMatches, ansi.red) : ansi.red(entry.message);
|
|
94601
|
-
|
|
94687
|
+
result = tsColored + msg;
|
|
94688
|
+
} else if (filterMatches && filterMatches.length > 0) {
|
|
94689
|
+
result = tsColored + highlightMatches(entry.message, filterMatches);
|
|
94690
|
+
} else {
|
|
94691
|
+
result = tsColored + colorizeTokens(entry.message);
|
|
94602
94692
|
}
|
|
94603
|
-
if (filterMatches
|
|
94604
|
-
|
|
94693
|
+
if (!filterMatches) {
|
|
94694
|
+
colorizedCache.set(entry, result);
|
|
94605
94695
|
}
|
|
94606
|
-
return
|
|
94696
|
+
return result;
|
|
94607
94697
|
}
|
|
94608
94698
|
function highlightMatches(text, matches, baseFn) {
|
|
94609
94699
|
if (matches.length === 0) return baseFn ? baseFn(text) : colorizeTokens(text);
|
|
@@ -94765,8 +94855,8 @@ var ContainersPanel = class {
|
|
|
94765
94855
|
label: "Logs",
|
|
94766
94856
|
render: (_item, metrics) => {
|
|
94767
94857
|
const logs = metrics.selectedContainerLogs;
|
|
94768
|
-
if (logs.length === 0) return "No logs available. Select a container to view logs.";
|
|
94769
|
-
return renderLogLines(logs, metrics.logFilterString, metrics.logFilterMode, metrics.logSeverityCounts)
|
|
94858
|
+
if (logs.length === 0) return ["No logs available. Select a container to view logs."];
|
|
94859
|
+
return renderLogLines(logs, metrics.logFilterString, metrics.logFilterMode, metrics.logSeverityCounts);
|
|
94770
94860
|
},
|
|
94771
94861
|
autoScrollBottom: true
|
|
94772
94862
|
},
|
|
@@ -95065,8 +95155,8 @@ var ServicesPanel = class {
|
|
|
95065
95155
|
label: "Logs",
|
|
95066
95156
|
render: (_item, metrics) => {
|
|
95067
95157
|
const logs = metrics.selectedComposeLogs;
|
|
95068
|
-
if (logs.length === 0) return "No compose logs. Logs will appear when a service produces output.";
|
|
95069
|
-
return renderLogLines(logs, metrics.logFilterString, metrics.logFilterMode)
|
|
95158
|
+
if (logs.length === 0) return ["No compose logs. Logs will appear when a service produces output."];
|
|
95159
|
+
return renderLogLines(logs, metrics.logFilterString, metrics.logFilterMode);
|
|
95070
95160
|
},
|
|
95071
95161
|
autoScrollBottom: true
|
|
95072
95162
|
}
|
|
@@ -95479,6 +95569,8 @@ var BaseStreamManager = class {
|
|
|
95479
95569
|
streamPromise = null;
|
|
95480
95570
|
reconnect = new import_sidekick_docker_shared6.ReconnectScheduler();
|
|
95481
95571
|
onChange;
|
|
95572
|
+
streamController = null;
|
|
95573
|
+
streamGeneration = 0;
|
|
95482
95574
|
constructor(onChange) {
|
|
95483
95575
|
this.onChange = onChange;
|
|
95484
95576
|
this.currentId = this.emptyId();
|
|
@@ -95492,25 +95584,29 @@ var BaseStreamManager = class {
|
|
|
95492
95584
|
if (!this.isValidId(id)) return;
|
|
95493
95585
|
this.aborted = false;
|
|
95494
95586
|
this.reconnect.reset();
|
|
95587
|
+
this.streamController = new AbortController();
|
|
95588
|
+
this.streamGeneration++;
|
|
95495
95589
|
this.onBeforeStream();
|
|
95496
|
-
this.streamPromise = this.runStream(id);
|
|
95590
|
+
this.streamPromise = this.runStream(id, this.streamController.signal, this.streamGeneration);
|
|
95497
95591
|
}
|
|
95498
|
-
async runStream(id) {
|
|
95592
|
+
async runStream(id, signal, generation) {
|
|
95499
95593
|
try {
|
|
95500
|
-
for await (const item of this.createStream(id)) {
|
|
95501
|
-
if (this.aborted || !this.isSameId(id, this.currentId)) break;
|
|
95594
|
+
for await (const item of this.createStream(id, signal)) {
|
|
95595
|
+
if (signal.aborted || this.aborted || !this.isSameId(id, this.currentId)) break;
|
|
95502
95596
|
this.processItem(id, item);
|
|
95503
95597
|
this.onChange();
|
|
95504
95598
|
}
|
|
95505
95599
|
this.reconnect.reset();
|
|
95506
95600
|
} catch (err) {
|
|
95601
|
+
if (signal.aborted) return;
|
|
95507
95602
|
console.debug(`${this.streamLabel} stream error:`, (0, import_sidekick_docker_shared6.errorMessage)(err));
|
|
95508
95603
|
}
|
|
95509
|
-
if (!this.aborted && this.isSameId(id, this.currentId)) {
|
|
95604
|
+
if (!signal.aborted && !this.aborted && this.isSameId(id, this.currentId) && generation === this.streamGeneration) {
|
|
95510
95605
|
const scheduled = this.reconnect.schedule(() => {
|
|
95511
|
-
if (!this.aborted && this.isSameId(id, this.currentId)) {
|
|
95606
|
+
if (!this.aborted && this.isSameId(id, this.currentId) && generation === this.streamGeneration) {
|
|
95607
|
+
this.streamController = new AbortController();
|
|
95512
95608
|
this.onBeforeStream();
|
|
95513
|
-
this.streamPromise = this.runStream(id);
|
|
95609
|
+
this.streamPromise = this.runStream(id, this.streamController.signal, generation);
|
|
95514
95610
|
}
|
|
95515
95611
|
});
|
|
95516
95612
|
if (!scheduled) {
|
|
@@ -95521,6 +95617,8 @@ var BaseStreamManager = class {
|
|
|
95521
95617
|
stop() {
|
|
95522
95618
|
this.aborted = true;
|
|
95523
95619
|
this.currentId = this.emptyId();
|
|
95620
|
+
this.streamController?.abort();
|
|
95621
|
+
this.streamController = null;
|
|
95524
95622
|
this.streamPromise = null;
|
|
95525
95623
|
this.reconnect.clear();
|
|
95526
95624
|
this.onStop();
|
|
@@ -95561,8 +95659,8 @@ var LogStreamManager = class extends BaseStreamManager {
|
|
|
95561
95659
|
idLabel(id) {
|
|
95562
95660
|
return id ?? "(none)";
|
|
95563
95661
|
}
|
|
95564
|
-
createStream(id) {
|
|
95565
|
-
return this.client.streamLogs(id, { follow: true, tail: 100 });
|
|
95662
|
+
createStream(id, signal) {
|
|
95663
|
+
return this.client.streamLogs(id, { follow: true, tail: 100 }, signal);
|
|
95566
95664
|
}
|
|
95567
95665
|
processItem(_id, entry) {
|
|
95568
95666
|
this.logs.push(entry);
|
|
@@ -95594,6 +95692,9 @@ var LogStreamManager = class extends BaseStreamManager {
|
|
|
95594
95692
|
getCurrentContainerId() {
|
|
95595
95693
|
return this.currentId;
|
|
95596
95694
|
}
|
|
95695
|
+
getTemplateDiagnostics() {
|
|
95696
|
+
return this.templateEngine.getDiagnostics();
|
|
95697
|
+
}
|
|
95597
95698
|
};
|
|
95598
95699
|
|
|
95599
95700
|
// src/dashboard/StatsStreamManager.ts
|
|
@@ -95618,8 +95719,8 @@ var StatsStreamManager = class extends BaseStreamManager {
|
|
|
95618
95719
|
idLabel(id) {
|
|
95619
95720
|
return id ?? "(none)";
|
|
95620
95721
|
}
|
|
95621
|
-
createStream(id) {
|
|
95622
|
-
return this.client.streamStats(id);
|
|
95722
|
+
createStream(id, signal) {
|
|
95723
|
+
return this.client.streamStats(id, signal);
|
|
95623
95724
|
}
|
|
95624
95725
|
processItem(id, stats) {
|
|
95625
95726
|
this.collector.push(id, stats);
|
|
@@ -95659,8 +95760,8 @@ var ComposeLogStreamManager = class extends BaseStreamManager {
|
|
|
95659
95760
|
idLabel(id) {
|
|
95660
95761
|
return id.project ?? "(none)";
|
|
95661
95762
|
}
|
|
95662
|
-
createStream(id) {
|
|
95663
|
-
return this.composeClient.streamLogs(id.project, id.service ?? void 0);
|
|
95763
|
+
createStream(id, signal) {
|
|
95764
|
+
return this.composeClient.streamLogs(id.project, id.service ?? void 0, 100, signal);
|
|
95664
95765
|
}
|
|
95665
95766
|
processItem(_id, entry) {
|
|
95666
95767
|
this.logs.push(entry);
|
|
@@ -97222,13 +97323,13 @@ function Dashboard({ panels, metrics, onViewStateChange, execTriggerRef, onExecF
|
|
|
97222
97323
|
logFilterString: state.logFilterString,
|
|
97223
97324
|
logFilterMode: state.logFilterMode
|
|
97224
97325
|
};
|
|
97225
|
-
let
|
|
97326
|
+
let detailLines = [];
|
|
97226
97327
|
if (selectedItem && detailTabs.length > 0 && tabIdx >= 0) {
|
|
97227
|
-
|
|
97328
|
+
const result = detailTabs[tabIdx].render(selectedItem, enrichedMetrics);
|
|
97329
|
+
detailLines = Array.isArray(result) ? result : result.split("\n");
|
|
97228
97330
|
} else if (!selectedItem) {
|
|
97229
|
-
|
|
97331
|
+
detailLines = ["(no item selected)"];
|
|
97230
97332
|
}
|
|
97231
|
-
const detailLines = detailContent.split("\n");
|
|
97232
97333
|
const detailViewportHeight = Math.max(1, rows - RESERVED_UI_ROWS);
|
|
97233
97334
|
const activeTab = detailTabs[tabIdx];
|
|
97234
97335
|
const shouldAutoScroll = activeTab?.autoScrollBottom ?? false;
|
|
@@ -97380,8 +97481,8 @@ function Dashboard({ panels, metrics, onViewStateChange, execTriggerRef, onExecF
|
|
|
97380
97481
|
)
|
|
97381
97482
|
] })
|
|
97382
97483
|
] }),
|
|
97383
|
-
state.overlay === "help" && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(HelpOverlay, { panels, activePanelIndex: state.activePanelIndex, version: "0.2.
|
|
97384
|
-
state.overlay === "version" && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VersionOverlay, { version: "0.2.
|
|
97484
|
+
state.overlay === "help" && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(HelpOverlay, { panels, activePanelIndex: state.activePanelIndex, version: "0.2.5" }),
|
|
97485
|
+
state.overlay === "version" && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VersionOverlay, { version: "0.2.5" }),
|
|
97385
97486
|
state.overlay === "exec" && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
97386
97487
|
ExecOverlay,
|
|
97387
97488
|
{
|
|
@@ -97398,7 +97499,7 @@ function Dashboard({ panels, metrics, onViewStateChange, execTriggerRef, onExecF
|
|
|
97398
97499
|
filterString: state.filterString,
|
|
97399
97500
|
containerCount: metrics.containers.length,
|
|
97400
97501
|
runningCount,
|
|
97401
|
-
version: "0.2.
|
|
97502
|
+
version: "0.2.5",
|
|
97402
97503
|
matchCount: state.filterString ? currentItems.length : void 0,
|
|
97403
97504
|
totalCount: state.filterString ? totalItemCount : void 0,
|
|
97404
97505
|
lastRefresh: metrics.lastRefresh,
|
|
@@ -97463,6 +97564,22 @@ async function dashboardAction(_opts, cmd) {
|
|
|
97463
97564
|
let composeLogFlushTimer = null;
|
|
97464
97565
|
let secondaryLogFlushTimer = null;
|
|
97465
97566
|
let secondaryComposeLogFlushTimer = null;
|
|
97567
|
+
let renderTimer = null;
|
|
97568
|
+
function scheduleRender() {
|
|
97569
|
+
if (renderTimer) return;
|
|
97570
|
+
renderTimer = setTimeout(() => {
|
|
97571
|
+
renderTimer = null;
|
|
97572
|
+
instance.rerender(
|
|
97573
|
+
import_react37.default.createElement(Dashboard, {
|
|
97574
|
+
panels,
|
|
97575
|
+
metrics: getEnrichedMetrics(),
|
|
97576
|
+
onViewStateChange,
|
|
97577
|
+
execTriggerRef,
|
|
97578
|
+
onExecFallback
|
|
97579
|
+
})
|
|
97580
|
+
);
|
|
97581
|
+
}, 200);
|
|
97582
|
+
}
|
|
97466
97583
|
const logManager = new LogStreamManager(client, () => {
|
|
97467
97584
|
if (logFlushTimer) return;
|
|
97468
97585
|
logFlushTimer = setTimeout(() => {
|
|
@@ -97644,6 +97761,17 @@ async function dashboardAction(_opts, cmd) {
|
|
|
97644
97761
|
const refreshInterval = setInterval(() => {
|
|
97645
97762
|
state.refresh().then(() => scheduleRender()).catch((e) => console.debug("periodic refresh failed:", e));
|
|
97646
97763
|
}, 3e4);
|
|
97764
|
+
let debugInterval = null;
|
|
97765
|
+
if (process.env.SIDEKICK_DEBUG_STREAMS === "1") {
|
|
97766
|
+
debugInterval = setInterval(() => {
|
|
97767
|
+
const mem = process.memoryUsage();
|
|
97768
|
+
const heapMB = (mem.heapUsed / 1024 / 1024).toFixed(1);
|
|
97769
|
+
const rssMB = (mem.rss / 1024 / 1024).toFixed(1);
|
|
97770
|
+
const templateDiag = logManager.getTemplateDiagnostics();
|
|
97771
|
+
const secondaryDiag = secondaryLogManager.getTemplateDiagnostics();
|
|
97772
|
+
console.debug(`[sidekick-debug] heap=${heapMB}MB rss=${rssMB}MB templates=${JSON.stringify(templateDiag)} secondary=${JSON.stringify(secondaryDiag)}`);
|
|
97773
|
+
}, 6e4);
|
|
97774
|
+
}
|
|
97647
97775
|
const execTriggerRef = { current: null };
|
|
97648
97776
|
const onExecFallback = (containerId) => {
|
|
97649
97777
|
instance.clear();
|
|
@@ -97690,7 +97818,6 @@ async function dashboardAction(_opts, cmd) {
|
|
|
97690
97818
|
servicesPanel.setOnCopyLogs((text) => {
|
|
97691
97819
|
copyToClipboard(text);
|
|
97692
97820
|
});
|
|
97693
|
-
let renderTimer = null;
|
|
97694
97821
|
function getEnrichedMetrics() {
|
|
97695
97822
|
const m = state.getMetrics();
|
|
97696
97823
|
m.logSeverityCounts = logSeverityCounts;
|
|
@@ -97700,21 +97827,6 @@ async function dashboardAction(_opts, cmd) {
|
|
|
97700
97827
|
m.secondaryLogSeverityTimeSeries = secondaryLogManager.getSeverityTimeSeries();
|
|
97701
97828
|
return m;
|
|
97702
97829
|
}
|
|
97703
|
-
function scheduleRender() {
|
|
97704
|
-
if (renderTimer) return;
|
|
97705
|
-
renderTimer = setTimeout(() => {
|
|
97706
|
-
renderTimer = null;
|
|
97707
|
-
instance.rerender(
|
|
97708
|
-
import_react37.default.createElement(Dashboard, {
|
|
97709
|
-
panels,
|
|
97710
|
-
metrics: getEnrichedMetrics(),
|
|
97711
|
-
onViewStateChange,
|
|
97712
|
-
execTriggerRef,
|
|
97713
|
-
onExecFallback
|
|
97714
|
-
})
|
|
97715
|
-
);
|
|
97716
|
-
}, 100);
|
|
97717
|
-
}
|
|
97718
97830
|
let stopped = false;
|
|
97719
97831
|
function cleanup() {
|
|
97720
97832
|
if (stopped) return;
|
|
@@ -97759,6 +97871,10 @@ async function dashboardAction(_opts, cmd) {
|
|
|
97759
97871
|
clearInterval(refreshInterval);
|
|
97760
97872
|
} catch {
|
|
97761
97873
|
}
|
|
97874
|
+
try {
|
|
97875
|
+
if (debugInterval) clearInterval(debugInterval);
|
|
97876
|
+
} catch {
|
|
97877
|
+
}
|
|
97762
97878
|
try {
|
|
97763
97879
|
watcher.stop();
|
|
97764
97880
|
} catch {
|
|
@@ -97839,7 +97955,7 @@ async function logsAction(container, opts) {
|
|
|
97839
97955
|
|
|
97840
97956
|
// src/cli.ts
|
|
97841
97957
|
var program2 = new Command();
|
|
97842
|
-
program2.name("sidekick-docker").description("Docker management TUI dashboard").version("0.2.
|
|
97958
|
+
program2.name("sidekick-docker").description("Docker management TUI dashboard").version("0.2.5").option("--socket <path>", "Docker socket path").action(async (_opts, cmd) => {
|
|
97843
97959
|
await dashboardAction(_opts, cmd);
|
|
97844
97960
|
});
|
|
97845
97961
|
program2.command("ps").description("List containers").option("-a, --all", "Show all containers (default: running only)", false).action(async (opts) => {
|