sidekick-docker 0.2.1 → 0.2.2

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 CHANGED
@@ -97,6 +97,7 @@ The dashboard has 5 panels, each mapped to a number key:
97
97
  | `r` | Restart |
98
98
  | `R` | Remove (with confirmation) |
99
99
  | `e` | Exec into container |
100
+ | `c` | Copy logs to clipboard |
100
101
 
101
102
  ### Compose Actions (via context menu)
102
103
 
@@ -106,6 +107,7 @@ The dashboard has 5 panels, each mapped to a number key:
106
107
  | `d` | Down (stop project) |
107
108
  | `r` | Restart |
108
109
  | `S` | Stop |
110
+ | `c` | Copy logs to clipboard |
109
111
 
110
112
  ## Features
111
113
 
@@ -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 ComposeClient2 = class {
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 = ComposeClient2;
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 = filterLine2;
56514
+ exports2.filterLine = filterLine3;
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 filterLine2(line, query, mode) {
56549
+ function filterLine3(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 import_sidekick_docker_shared13 = __toESM(require_dist(), 1);
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
@@ -94965,6 +94965,7 @@ var ContainersPanel = class {
94965
94965
  };
94966
94966
 
94967
94967
  // src/dashboard/panels/ServicesPanel.ts
94968
+ var import_sidekick_docker_shared5 = __toESM(require_dist(), 1);
94968
94969
  function getProjectName(d) {
94969
94970
  return d.type === "project" ? d.project.name : d.service.projectName;
94970
94971
  }
@@ -94976,12 +94977,17 @@ var ServicesPanel = class {
94976
94977
  onAction;
94977
94978
  onError;
94978
94979
  cwd;
94980
+ onCopyLogs;
94981
+ lastMetrics = null;
94979
94982
  constructor(composeClient, onAction, cwd2, onError) {
94980
94983
  this.composeClient = composeClient;
94981
94984
  this.onAction = onAction;
94982
94985
  this.onError = onError ?? defaultOnError;
94983
94986
  this.cwd = cwd2;
94984
94987
  }
94988
+ setOnCopyLogs(handler) {
94989
+ this.onCopyLogs = handler;
94990
+ }
94985
94991
  detailTabs = [
94986
94992
  {
94987
94993
  label: "Info",
@@ -95021,6 +95027,7 @@ var ServicesPanel = class {
95021
95027
  }
95022
95028
  ];
95023
95029
  getItems(metrics) {
95030
+ this.lastMetrics = metrics;
95024
95031
  const items = [];
95025
95032
  let sortKey = 0;
95026
95033
  for (const project of metrics.composeProjects) {
@@ -95115,6 +95122,23 @@ var ServicesPanel = class {
95115
95122
  });
95116
95123
  },
95117
95124
  condition: (item) => item.data !== null
95125
+ },
95126
+ {
95127
+ key: "c",
95128
+ label: "Copy Logs",
95129
+ handler: () => {
95130
+ if (!this.lastMetrics || !this.onCopyLogs) return;
95131
+ const logs = this.lastMetrics.selectedComposeLogs;
95132
+ const query = this.lastMetrics.logFilterString;
95133
+ const mode = this.lastMetrics.logFilterMode;
95134
+ let lines;
95135
+ if (query) {
95136
+ lines = logs.filter((l) => (0, import_sidekick_docker_shared5.filterLine)(l.message, query, mode).matched).map((l) => l.message);
95137
+ } else {
95138
+ lines = logs.map((l) => l.message);
95139
+ }
95140
+ this.onCopyLogs(lines.join("\n"));
95141
+ }
95118
95142
  }
95119
95143
  ];
95120
95144
  }
@@ -95400,15 +95424,15 @@ var NetworksPanel = class {
95400
95424
  };
95401
95425
 
95402
95426
  // src/dashboard/LogStreamManager.ts
95403
- var import_sidekick_docker_shared6 = __toESM(require_dist(), 1);
95427
+ var import_sidekick_docker_shared7 = __toESM(require_dist(), 1);
95404
95428
 
95405
95429
  // src/dashboard/BaseStreamManager.ts
95406
- var import_sidekick_docker_shared5 = __toESM(require_dist(), 1);
95430
+ var import_sidekick_docker_shared6 = __toESM(require_dist(), 1);
95407
95431
  var BaseStreamManager = class {
95408
95432
  currentId;
95409
95433
  aborted = false;
95410
95434
  streamPromise = null;
95411
- reconnect = new import_sidekick_docker_shared5.ReconnectScheduler();
95435
+ reconnect = new import_sidekick_docker_shared6.ReconnectScheduler();
95412
95436
  onChange;
95413
95437
  constructor(onChange) {
95414
95438
  this.onChange = onChange;
@@ -95435,7 +95459,7 @@ var BaseStreamManager = class {
95435
95459
  }
95436
95460
  this.reconnect.reset();
95437
95461
  } catch (err) {
95438
- console.debug(`${this.streamLabel} stream error:`, (0, import_sidekick_docker_shared5.errorMessage)(err));
95462
+ console.debug(`${this.streamLabel} stream error:`, (0, import_sidekick_docker_shared6.errorMessage)(err));
95439
95463
  }
95440
95464
  if (!this.aborted && this.isSameId(id, this.currentId)) {
95441
95465
  const scheduled = this.reconnect.schedule(() => {
@@ -95472,9 +95496,9 @@ var BaseStreamManager = class {
95472
95496
  var LogStreamManager = class extends BaseStreamManager {
95473
95497
  client;
95474
95498
  logs = [];
95475
- analytics = new import_sidekick_docker_shared6.LogAnalytics();
95476
- timeSeries = new import_sidekick_docker_shared6.LogSeverityTimeSeries();
95477
- templateEngine = new import_sidekick_docker_shared6.LogTemplateEngine();
95499
+ analytics = new import_sidekick_docker_shared7.LogAnalytics();
95500
+ timeSeries = new import_sidekick_docker_shared7.LogSeverityTimeSeries();
95501
+ templateEngine = new import_sidekick_docker_shared7.LogTemplateEngine();
95478
95502
  streamLabel = "log";
95479
95503
  constructor(client, onChange) {
95480
95504
  super(onChange);
@@ -95500,7 +95524,7 @@ var LogStreamManager = class extends BaseStreamManager {
95500
95524
  const severity = this.analytics.push(entry.message);
95501
95525
  this.timeSeries.push(severity);
95502
95526
  this.templateEngine.push(entry.message);
95503
- if (this.logs.length > import_sidekick_docker_shared6.MAX_LOG_LINES) {
95527
+ if (this.logs.length > import_sidekick_docker_shared7.MAX_LOG_LINES) {
95504
95528
  this.logs.shift();
95505
95529
  }
95506
95530
  }
@@ -95569,7 +95593,7 @@ var StatsStreamManager = class extends BaseStreamManager {
95569
95593
  };
95570
95594
 
95571
95595
  // src/dashboard/ComposeLogStreamManager.ts
95572
- var import_sidekick_docker_shared7 = __toESM(require_dist(), 1);
95596
+ var import_sidekick_docker_shared8 = __toESM(require_dist(), 1);
95573
95597
  var ComposeLogStreamManager = class extends BaseStreamManager {
95574
95598
  composeClient;
95575
95599
  logs = [];
@@ -95595,7 +95619,7 @@ var ComposeLogStreamManager = class extends BaseStreamManager {
95595
95619
  }
95596
95620
  processItem(_id, entry) {
95597
95621
  this.logs.push(entry);
95598
- if (this.logs.length > import_sidekick_docker_shared7.MAX_LOG_LINES) {
95622
+ if (this.logs.length > import_sidekick_docker_shared8.MAX_LOG_LINES) {
95599
95623
  this.logs.shift();
95600
95624
  }
95601
95625
  }
@@ -96232,7 +96256,7 @@ function DetailPane({ lines, scrollOffset, viewportHeight, focused }) {
96232
96256
  // src/dashboard/ink/StatusBar.tsx
96233
96257
  var import_react32 = __toESM(require_react(), 1);
96234
96258
  await init_build2();
96235
- var import_sidekick_docker_shared8 = __toESM(require_dist(), 1);
96259
+ var import_sidekick_docker_shared9 = __toESM(require_dist(), 1);
96236
96260
  var import_jsx_runtime5 = __toESM(require_jsx_runtime(), 1);
96237
96261
  function formatAgo(date) {
96238
96262
  const secs = Math.floor((Date.now() - date.getTime()) / 1e3);
@@ -96250,8 +96274,8 @@ function StatusBar({ daemonConnected, focusTarget, panelActionHints, filterStrin
96250
96274
  }, []);
96251
96275
  const ago = lastRefresh ? formatAgo(lastRefresh) : null;
96252
96276
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
96253
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { bold: true, color: "magenta", children: ` \u26A1 ${import_sidekick_docker_shared8.BRAND_INLINE}` }),
96254
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "gray", dimColor: true, children: ` ${import_sidekick_docker_shared8.BRAND_TAGLINE} v${version2}` }),
96277
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { bold: true, color: "magenta", children: ` \u26A1 ${import_sidekick_docker_shared9.BRAND_INLINE}` }),
96278
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "gray", dimColor: true, children: ` ${import_sidekick_docker_shared9.BRAND_TAGLINE} v${version2}` }),
96255
96279
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "gray", dimColor: true, children: ` ${SEP2} ` }),
96256
96280
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: daemonConnected ? "green" : "red", children: daemonConnected ? `\u25CF ${runningCount ?? 0}/${containerCount ?? 0}` : "\u25CB disconnected" }),
96257
96281
  ago && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: ago.stale ? "yellow" : "gray", dimColor: !ago.stale, children: ` \u21BB ${ago.text}` }),
@@ -96274,7 +96298,7 @@ function StatusBar({ daemonConnected, focusTarget, panelActionHints, filterStrin
96274
96298
 
96275
96299
  // src/dashboard/ink/HelpOverlay.tsx
96276
96300
  await init_build2();
96277
- var import_sidekick_docker_shared9 = __toESM(require_dist(), 1);
96301
+ var import_sidekick_docker_shared10 = __toESM(require_dist(), 1);
96278
96302
  var import_jsx_runtime6 = __toESM(require_jsx_runtime(), 1);
96279
96303
  var GLOBAL_BINDINGS = [
96280
96304
  { key: "1-5", label: "Switch panel" },
@@ -96300,7 +96324,7 @@ function HelpOverlay({ panels, activePanelIndex, version: version2 }) {
96300
96324
  const actions = panel.getActions();
96301
96325
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Box_default, { flexDirection: "column", flexGrow: 1, padding: 1, children: [
96302
96326
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Box_default, { children: [
96303
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, color: "magenta", children: `\u26A1 ${import_sidekick_docker_shared9.BRAND_INLINE} ${import_sidekick_docker_shared9.BRAND_TAGLINE}` }),
96327
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, color: "magenta", children: `\u26A1 ${import_sidekick_docker_shared10.BRAND_INLINE} ${import_sidekick_docker_shared10.BRAND_TAGLINE}` }),
96304
96328
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "gray", dimColor: true, children: ` v${version2}` })
96305
96329
  ] }),
96306
96330
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "" }),
@@ -96469,7 +96493,7 @@ function ToastNotification({ toast }) {
96469
96493
 
96470
96494
  // src/dashboard/ink/TooSmallOverlay.tsx
96471
96495
  await init_build2();
96472
- var import_sidekick_docker_shared10 = __toESM(require_dist(), 1);
96496
+ var import_sidekick_docker_shared11 = __toESM(require_dist(), 1);
96473
96497
  var import_jsx_runtime11 = __toESM(require_jsx_runtime(), 1);
96474
96498
  function TooSmallOverlay({ columns, rows }) {
96475
96499
  const needWidth = Math.max(0, 60 - columns);
@@ -96478,7 +96502,7 @@ function TooSmallOverlay({ columns, rows }) {
96478
96502
  if (needWidth > 0) hints.push(`${needWidth} col${needWidth > 1 ? "s" : ""} wider`);
96479
96503
  if (needHeight > 0) hints.push(`${needHeight} row${needHeight > 1 ? "s" : ""} taller`);
96480
96504
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { flexDirection: "column", justifyContent: "center", alignItems: "center", height: rows, width: columns, children: [
96481
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { bold: true, color: "magenta", children: `\u26A1 ${import_sidekick_docker_shared10.BRAND_INLINE}` }),
96505
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { bold: true, color: "magenta", children: `\u26A1 ${import_sidekick_docker_shared11.BRAND_INLINE}` }),
96482
96506
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { children: "" }),
96483
96507
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { color: "yellow", bold: true, children: "Terminal too small" }),
96484
96508
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { color: "gray", children: `${columns}\xD7${rows} \u2192 need ${hints.join(" and ")}` }),
@@ -96618,13 +96642,13 @@ function LogFilterOverlay({ filterString, filterMode }) {
96618
96642
  // src/dashboard/ink/VersionOverlay.tsx
96619
96643
  var import_react35 = __toESM(require_react(), 1);
96620
96644
  await init_build2();
96621
- var import_sidekick_docker_shared11 = __toESM(require_dist(), 1);
96645
+ var import_sidekick_docker_shared12 = __toESM(require_dist(), 1);
96622
96646
  var import_jsx_runtime15 = __toESM(require_jsx_runtime(), 1);
96623
96647
  function VersionOverlay({ version: version2 }) {
96624
- const phrase = import_react35.default.useMemo(() => (0, import_sidekick_docker_shared11.getRandomPhrase)(), []);
96648
+ const phrase = import_react35.default.useMemo(() => (0, import_sidekick_docker_shared12.getRandomPhrase)(), []);
96625
96649
  return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Box_default, { flexDirection: "column", flexGrow: 1, padding: 1, children: [
96626
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Text, { bold: true, color: "magenta", children: `\u26A1 ${import_sidekick_docker_shared11.BRAND_INLINE}` }),
96627
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Text, { color: "#2B4C7E", bold: true, children: `${import_sidekick_docker_shared11.BRAND_TAGLINE} v${version2}` }),
96650
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Text, { bold: true, color: "magenta", children: `\u26A1 ${import_sidekick_docker_shared12.BRAND_INLINE}` }),
96651
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Text, { color: "#2B4C7E", bold: true, children: `${import_sidekick_docker_shared12.BRAND_TAGLINE} v${version2}` }),
96628
96652
  /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Text, { children: "" }),
96629
96653
  /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Text, { color: "gray", dimColor: true, children: "\u2500".repeat(40) }),
96630
96654
  /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Text, { children: "" }),
@@ -96683,7 +96707,7 @@ function SortOverlay({ selectedIndex, currentField, reversed }) {
96683
96707
  }
96684
96708
 
96685
96709
  // src/dashboard/ink/Dashboard.tsx
96686
- var import_sidekick_docker_shared12 = __toESM(require_dist(), 1);
96710
+ var import_sidekick_docker_shared13 = __toESM(require_dist(), 1);
96687
96711
 
96688
96712
  // src/dashboard/ExecManager.ts
96689
96713
  var ExecManager = class {
@@ -96876,11 +96900,11 @@ function Dashboard({ panels, metrics, onViewStateChange, execTriggerRef, onExecF
96876
96900
  const { columns, rows } = useTerminalSize();
96877
96901
  const toastIdRef = (0, import_react36.useRef)(0);
96878
96902
  const execManagerRef = (0, import_react36.useRef)(null);
96879
- const [phrase, setPhrase] = import_react36.default.useState(() => (0, import_sidekick_docker_shared12.getRandomPhrase)());
96903
+ const [phrase, setPhrase] = import_react36.default.useState(() => (0, import_sidekick_docker_shared13.getRandomPhrase)());
96880
96904
  const phraseTimerRef = (0, import_react36.useRef)(null);
96881
96905
  const rotatePhraseRef = (0, import_react36.useRef)(void 0);
96882
96906
  rotatePhraseRef.current = () => {
96883
- setPhrase((0, import_sidekick_docker_shared12.getRandomPhrase)());
96907
+ setPhrase((0, import_sidekick_docker_shared13.getRandomPhrase)());
96884
96908
  if (phraseTimerRef.current) clearTimeout(phraseTimerRef.current);
96885
96909
  phraseTimerRef.current = setTimeout(() => rotatePhraseRef.current?.(), 7e3);
96886
96910
  };
@@ -97159,8 +97183,8 @@ function Dashboard({ panels, metrics, onViewStateChange, execTriggerRef, onExecF
97159
97183
  )
97160
97184
  ] })
97161
97185
  ] }),
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" }),
97186
+ state.overlay === "help" && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(HelpOverlay, { panels, activePanelIndex: state.activePanelIndex, version: "0.2.2" }),
97187
+ state.overlay === "version" && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(VersionOverlay, { version: "0.2.2" }),
97164
97188
  state.overlay === "exec" && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
97165
97189
  ExecOverlay,
97166
97190
  {
@@ -97177,7 +97201,7 @@ function Dashboard({ panels, metrics, onViewStateChange, execTriggerRef, onExecF
97177
97201
  filterString: state.filterString,
97178
97202
  containerCount: metrics.containers.length,
97179
97203
  runningCount,
97180
- version: "0.2.1",
97204
+ version: "0.2.2",
97181
97205
  matchCount: state.filterString ? currentItems.length : void 0,
97182
97206
  totalCount: state.filterString ? totalItemCount : void 0,
97183
97207
  lastRefresh: metrics.lastRefresh,
@@ -97222,7 +97246,7 @@ function Dashboard({ panels, metrics, onViewStateChange, execTriggerRef, onExecF
97222
97246
  async function dashboardAction(_opts, cmd) {
97223
97247
  const globalOpts = cmd.parent?.opts() ?? cmd.opts();
97224
97248
  const socketPath = globalOpts.socket;
97225
- const client = new import_sidekick_docker_shared13.DockerClient(socketPath ? { socketPath } : void 0);
97249
+ const client = new import_sidekick_docker_shared14.DockerClient(socketPath ? { socketPath } : void 0);
97226
97250
  const ok = await client.ping();
97227
97251
  if (!ok) {
97228
97252
  console.error("Error: Cannot connect to Docker daemon. Is Docker running?");
@@ -97231,7 +97255,7 @@ async function dashboardAction(_opts, cmd) {
97231
97255
  const cwd2 = process.cwd();
97232
97256
  const state = new DockerState(client, cwd2);
97233
97257
  await state.refresh();
97234
- const composeClient = new import_sidekick_docker_shared13.ComposeClient();
97258
+ const composeClient = new import_sidekick_docker_shared14.ComposeClient();
97235
97259
  const onAction = () => {
97236
97260
  state.refresh().then(() => scheduleRender()).catch((e) => console.debug("refresh failed:", e));
97237
97261
  };
@@ -97347,7 +97371,7 @@ async function dashboardAction(_opts, cmd) {
97347
97371
  new VolumesPanel(client, onAction, onError),
97348
97372
  new NetworksPanel(client, onAction, onError)
97349
97373
  ];
97350
- const watcher = new import_sidekick_docker_shared13.EventWatcher(client, {
97374
+ const watcher = new import_sidekick_docker_shared14.EventWatcher(client, {
97351
97375
  onEvent: (event) => {
97352
97376
  state.processEvent(event);
97353
97377
  scheduleRender();
@@ -97392,7 +97416,7 @@ async function dashboardAction(_opts, cmd) {
97392
97416
  const containersPanel = panels[0];
97393
97417
  containersPanel.setOnExec((containerId) => {
97394
97418
  const container = state.getMetrics().containers.find((c) => c.id === containerId);
97395
- const name = container?.name ?? (0, import_sidekick_docker_shared13.shortId)(containerId);
97419
+ const name = container?.name ?? (0, import_sidekick_docker_shared14.shortId)(containerId);
97396
97420
  if (execTriggerRef.current) {
97397
97421
  execTriggerRef.current(containerId, name);
97398
97422
  } else {
@@ -97402,6 +97426,10 @@ async function dashboardAction(_opts, cmd) {
97402
97426
  containersPanel.setOnCopyLogs((text) => {
97403
97427
  copyToClipboard(text);
97404
97428
  });
97429
+ const servicesPanel = panels[1];
97430
+ servicesPanel.setOnCopyLogs((text) => {
97431
+ copyToClipboard(text);
97432
+ });
97405
97433
  let renderTimer = null;
97406
97434
  function getEnrichedMetrics() {
97407
97435
  const m = state.getMetrics();
@@ -97473,9 +97501,9 @@ async function dashboardAction(_opts, cmd) {
97473
97501
  }
97474
97502
 
97475
97503
  // src/commands/ps.ts
97476
- var import_sidekick_docker_shared14 = __toESM(require_dist(), 1);
97504
+ var import_sidekick_docker_shared15 = __toESM(require_dist(), 1);
97477
97505
  async function psAction(opts) {
97478
- const client = new import_sidekick_docker_shared14.DockerClient();
97506
+ const client = new import_sidekick_docker_shared15.DockerClient();
97479
97507
  const ok = await client.ping();
97480
97508
  if (!ok) {
97481
97509
  console.error("Error: Cannot connect to Docker daemon. Is Docker running?");
@@ -97491,7 +97519,7 @@ async function psAction(opts) {
97491
97519
  console.log("-".repeat(100));
97492
97520
  for (const c of containers) {
97493
97521
  const row = [
97494
- (0, import_sidekick_docker_shared14.shortId)(c.id).padEnd(20),
97522
+ (0, import_sidekick_docker_shared15.shortId)(c.id).padEnd(20),
97495
97523
  `${(0, import_sidekick_docker_shared3.stateIcon)(c.state)} ${c.name}`.padEnd(20),
97496
97524
  c.image.padEnd(20),
97497
97525
  formatUptime(c.status).padEnd(20),
@@ -97502,9 +97530,9 @@ async function psAction(opts) {
97502
97530
  }
97503
97531
 
97504
97532
  // src/commands/logs.ts
97505
- var import_sidekick_docker_shared15 = __toESM(require_dist(), 1);
97533
+ var import_sidekick_docker_shared16 = __toESM(require_dist(), 1);
97506
97534
  async function logsAction(container, opts) {
97507
- const client = new import_sidekick_docker_shared15.DockerClient();
97535
+ const client = new import_sidekick_docker_shared16.DockerClient();
97508
97536
  const ok = await client.ping();
97509
97537
  if (!ok) {
97510
97538
  console.error("Error: Cannot connect to Docker daemon. Is Docker running?");
@@ -97515,13 +97543,13 @@ async function logsAction(container, opts) {
97515
97543
  follow: opts.follow ?? true,
97516
97544
  tail: parseInt(opts.tail || "100", 10)
97517
97545
  })) {
97518
- const ts = entry.timestamp ? (0, import_sidekick_docker_shared15.formatTimestampTime)(entry.timestamp) : "";
97546
+ const ts = entry.timestamp ? (0, import_sidekick_docker_shared16.formatTimestampTime)(entry.timestamp) : "";
97519
97547
  const prefix = entry.stream === "stderr" ? "\x1B[31m" : "";
97520
97548
  const reset = entry.stream === "stderr" ? "\x1B[0m" : "";
97521
97549
  console.log(`${prefix}${ts} ${entry.message}${reset}`);
97522
97550
  }
97523
97551
  } catch (err) {
97524
- const msg = (0, import_sidekick_docker_shared15.errorMessage)(err);
97552
+ const msg = (0, import_sidekick_docker_shared16.errorMessage)(err);
97525
97553
  if (msg.includes("no such container") || msg.includes("No such container")) {
97526
97554
  console.error(`Error: Container "${container}" not found.`);
97527
97555
  } else {
@@ -97533,7 +97561,7 @@ async function logsAction(container, opts) {
97533
97561
 
97534
97562
  // src/cli.ts
97535
97563
  var program2 = new Command();
97536
- program2.name("sidekick-docker").description("Docker management TUI dashboard").version("0.2.1").option("--socket <path>", "Docker socket path").action(async (_opts, cmd) => {
97564
+ program2.name("sidekick-docker").description("Docker management TUI dashboard").version("0.2.2").option("--socket <path>", "Docker socket path").action(async (_opts, cmd) => {
97537
97565
  await dashboardAction(_opts, cmd);
97538
97566
  });
97539
97567
  program2.command("ps").description("List containers").option("-a, --all", "Show all containers (default: running only)", false).action(async (opts) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sidekick-docker",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Docker management TUI dashboard",
5
5
  "author": "Cesar Andres Lopez <cesarandreslopez@gmail.com>",
6
6
  "repository": {