sidekick-docker 0.1.1 → 0.1.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 +6 -3
- package/dist/sidekick-docker.mjs +1572 -644
- package/package.json +1 -1
package/dist/sidekick-docker.mjs
CHANGED
|
@@ -15141,7 +15141,7 @@ var require_load_balancer_child_handler = __commonJS({
|
|
|
15141
15141
|
createSubchannel(subchannelAddress, subchannelArgs) {
|
|
15142
15142
|
return this.parent.channelControlHelper.createSubchannel(subchannelAddress, subchannelArgs);
|
|
15143
15143
|
}
|
|
15144
|
-
updateState(connectivityState, picker,
|
|
15144
|
+
updateState(connectivityState, picker, errorMessage5) {
|
|
15145
15145
|
var _a;
|
|
15146
15146
|
if (this.calledByPendingChild()) {
|
|
15147
15147
|
if (connectivityState === connectivity_state_1.ConnectivityState.CONNECTING) {
|
|
@@ -15153,7 +15153,7 @@ var require_load_balancer_child_handler = __commonJS({
|
|
|
15153
15153
|
} else if (!this.calledByCurrentChild()) {
|
|
15154
15154
|
return;
|
|
15155
15155
|
}
|
|
15156
|
-
this.parent.channelControlHelper.updateState(connectivityState, picker,
|
|
15156
|
+
this.parent.channelControlHelper.updateState(connectivityState, picker, errorMessage5);
|
|
15157
15157
|
}
|
|
15158
15158
|
requestReresolution() {
|
|
15159
15159
|
var _a;
|
|
@@ -15379,11 +15379,11 @@ var require_resolving_load_balancer = __commonJS({
|
|
|
15379
15379
|
this.updateResolution();
|
|
15380
15380
|
}
|
|
15381
15381
|
},
|
|
15382
|
-
updateState: (newState, picker,
|
|
15382
|
+
updateState: (newState, picker, errorMessage5) => {
|
|
15383
15383
|
this.latestChildState = newState;
|
|
15384
15384
|
this.latestChildPicker = picker;
|
|
15385
|
-
this.latestChildErrorMessage =
|
|
15386
|
-
this.updateState(newState, picker,
|
|
15385
|
+
this.latestChildErrorMessage = errorMessage5;
|
|
15386
|
+
this.updateState(newState, picker, errorMessage5);
|
|
15387
15387
|
},
|
|
15388
15388
|
addChannelzChild: channelControlHelper.addChannelzChild.bind(channelControlHelper),
|
|
15389
15389
|
removeChannelzChild: channelControlHelper.removeChannelzChild.bind(channelControlHelper)
|
|
@@ -15447,13 +15447,13 @@ var require_resolving_load_balancer = __commonJS({
|
|
|
15447
15447
|
}
|
|
15448
15448
|
this.backoffTimeout.runOnce();
|
|
15449
15449
|
}
|
|
15450
|
-
updateState(connectivityState, picker,
|
|
15450
|
+
updateState(connectivityState, picker, errorMessage5) {
|
|
15451
15451
|
trace((0, uri_parser_1.uriToString)(this.target) + " " + connectivity_state_1.ConnectivityState[this.currentState] + " -> " + connectivity_state_1.ConnectivityState[connectivityState]);
|
|
15452
15452
|
if (connectivityState === connectivity_state_1.ConnectivityState.IDLE) {
|
|
15453
15453
|
picker = new picker_1.QueuePicker(this, picker);
|
|
15454
15454
|
}
|
|
15455
15455
|
this.currentState = connectivityState;
|
|
15456
|
-
this.channelControlHelper.updateState(connectivityState, picker,
|
|
15456
|
+
this.channelControlHelper.updateState(connectivityState, picker, errorMessage5);
|
|
15457
15457
|
}
|
|
15458
15458
|
handleResolutionFailure(error) {
|
|
15459
15459
|
if (this.latestChildState === connectivity_state_1.ConnectivityState.IDLE) {
|
|
@@ -28353,13 +28353,13 @@ var require_subchannel = __commonJS({
|
|
|
28353
28353
|
* @param newState The state to transition to
|
|
28354
28354
|
* @returns True if the state changed, false otherwise
|
|
28355
28355
|
*/
|
|
28356
|
-
transitionToState(oldStates, newState,
|
|
28356
|
+
transitionToState(oldStates, newState, errorMessage5) {
|
|
28357
28357
|
var _a, _b;
|
|
28358
28358
|
if (oldStates.indexOf(this.connectivityState) === -1) {
|
|
28359
28359
|
return false;
|
|
28360
28360
|
}
|
|
28361
|
-
if (
|
|
28362
|
-
this.trace(connectivity_state_1.ConnectivityState[this.connectivityState] + " -> " + connectivity_state_1.ConnectivityState[newState] + ' with error "' +
|
|
28361
|
+
if (errorMessage5) {
|
|
28362
|
+
this.trace(connectivity_state_1.ConnectivityState[this.connectivityState] + " -> " + connectivity_state_1.ConnectivityState[newState] + ' with error "' + errorMessage5 + '"');
|
|
28363
28363
|
} else {
|
|
28364
28364
|
this.trace(connectivity_state_1.ConnectivityState[this.connectivityState] + " -> " + connectivity_state_1.ConnectivityState[newState]);
|
|
28365
28365
|
}
|
|
@@ -28400,7 +28400,7 @@ var require_subchannel = __commonJS({
|
|
|
28400
28400
|
throw new Error(`Invalid state: unknown ConnectivityState ${newState}`);
|
|
28401
28401
|
}
|
|
28402
28402
|
for (const listener of this.stateListeners) {
|
|
28403
|
-
listener(this, previousState, newState, this.keepaliveTime,
|
|
28403
|
+
listener(this, previousState, newState, this.keepaliveTime, errorMessage5);
|
|
28404
28404
|
}
|
|
28405
28405
|
return true;
|
|
28406
28406
|
}
|
|
@@ -29969,18 +29969,18 @@ var require_transport = __commonJS({
|
|
|
29969
29969
|
setImmediate(() => {
|
|
29970
29970
|
if (!reportedError) {
|
|
29971
29971
|
reportedError = true;
|
|
29972
|
-
reject(`${
|
|
29972
|
+
reject(`${errorMessage5.trim()} (${(/* @__PURE__ */ new Date()).toISOString()})`);
|
|
29973
29973
|
}
|
|
29974
29974
|
});
|
|
29975
29975
|
};
|
|
29976
29976
|
const errorHandler = (error) => {
|
|
29977
29977
|
var _a2;
|
|
29978
29978
|
(_a2 = this.session) === null || _a2 === void 0 ? void 0 : _a2.destroy();
|
|
29979
|
-
|
|
29980
|
-
this.trace("connection failed with error " +
|
|
29979
|
+
errorMessage5 = error.message;
|
|
29980
|
+
this.trace("connection failed with error " + errorMessage5);
|
|
29981
29981
|
if (!reportedError) {
|
|
29982
29982
|
reportedError = true;
|
|
29983
|
-
reject(`${
|
|
29983
|
+
reject(`${errorMessage5} (${(/* @__PURE__ */ new Date()).toISOString()})`);
|
|
29984
29984
|
}
|
|
29985
29985
|
};
|
|
29986
29986
|
const sessionOptions = {
|
|
@@ -30001,7 +30001,7 @@ var require_transport = __commonJS({
|
|
|
30001
30001
|
const defaultWin = (_h = (_g = (_f = http2.getDefaultSettings) === null || _f === void 0 ? void 0 : _f.call(http2)) === null || _g === void 0 ? void 0 : _g.initialWindowSize) !== null && _h !== void 0 ? _h : 65535;
|
|
30002
30002
|
const connWin = options["grpc-node.flow_control_window"];
|
|
30003
30003
|
this.session = session;
|
|
30004
|
-
let
|
|
30004
|
+
let errorMessage5 = "Failed to connect";
|
|
30005
30005
|
let reportedError = false;
|
|
30006
30006
|
session.unref();
|
|
30007
30007
|
session.once("remoteSettings", () => {
|
|
@@ -35224,8 +35224,8 @@ var require_load_balancer_pick_first = __commonJS({
|
|
|
35224
35224
|
this.currentState = connectivity_state_1.ConnectivityState.IDLE;
|
|
35225
35225
|
this.currentSubchannelIndex = 0;
|
|
35226
35226
|
this.currentPick = null;
|
|
35227
|
-
this.subchannelStateListener = (subchannel, previousState, newState, keepaliveTime,
|
|
35228
|
-
this.onSubchannelStateUpdate(subchannel, previousState, newState,
|
|
35227
|
+
this.subchannelStateListener = (subchannel, previousState, newState, keepaliveTime, errorMessage5) => {
|
|
35228
|
+
this.onSubchannelStateUpdate(subchannel, previousState, newState, errorMessage5);
|
|
35229
35229
|
};
|
|
35230
35230
|
this.pickedSubchannelHealthListener = () => this.calculateAndReportNewState();
|
|
35231
35231
|
this.stickyTransientFailureMode = false;
|
|
@@ -35248,26 +35248,26 @@ var require_load_balancer_pick_first = __commonJS({
|
|
|
35248
35248
|
var _a;
|
|
35249
35249
|
if (this.currentPick) {
|
|
35250
35250
|
if (this.reportHealthStatus && !this.currentPick.isHealthy()) {
|
|
35251
|
-
const
|
|
35251
|
+
const errorMessage5 = `Picked subchannel ${this.currentPick.getAddress()} is unhealthy`;
|
|
35252
35252
|
this.updateState(connectivity_state_1.ConnectivityState.TRANSIENT_FAILURE, new picker_1.UnavailablePicker({
|
|
35253
|
-
details:
|
|
35254
|
-
}),
|
|
35253
|
+
details: errorMessage5
|
|
35254
|
+
}), errorMessage5);
|
|
35255
35255
|
} else {
|
|
35256
35256
|
this.updateState(connectivity_state_1.ConnectivityState.READY, new PickFirstPicker(this.currentPick), null);
|
|
35257
35257
|
}
|
|
35258
35258
|
} else if (((_a = this.latestAddressList) === null || _a === void 0 ? void 0 : _a.length) === 0) {
|
|
35259
|
-
const
|
|
35259
|
+
const errorMessage5 = `No connection established. Last error: ${this.lastError}. Resolution note: ${this.latestResolutionNote}`;
|
|
35260
35260
|
this.updateState(connectivity_state_1.ConnectivityState.TRANSIENT_FAILURE, new picker_1.UnavailablePicker({
|
|
35261
|
-
details:
|
|
35262
|
-
}),
|
|
35261
|
+
details: errorMessage5
|
|
35262
|
+
}), errorMessage5);
|
|
35263
35263
|
} else if (this.children.length === 0) {
|
|
35264
35264
|
this.updateState(connectivity_state_1.ConnectivityState.IDLE, new picker_1.QueuePicker(this), null);
|
|
35265
35265
|
} else {
|
|
35266
35266
|
if (this.stickyTransientFailureMode) {
|
|
35267
|
-
const
|
|
35267
|
+
const errorMessage5 = `No connection established. Last error: ${this.lastError}. Resolution note: ${this.latestResolutionNote}`;
|
|
35268
35268
|
this.updateState(connectivity_state_1.ConnectivityState.TRANSIENT_FAILURE, new picker_1.UnavailablePicker({
|
|
35269
|
-
details:
|
|
35270
|
-
}),
|
|
35269
|
+
details: errorMessage5
|
|
35270
|
+
}), errorMessage5);
|
|
35271
35271
|
} else {
|
|
35272
35272
|
this.updateState(connectivity_state_1.ConnectivityState.CONNECTING, new picker_1.QueuePicker(this), null);
|
|
35273
35273
|
}
|
|
@@ -35301,7 +35301,7 @@ var require_load_balancer_pick_first = __commonJS({
|
|
|
35301
35301
|
this.currentPick = null;
|
|
35302
35302
|
}
|
|
35303
35303
|
}
|
|
35304
|
-
onSubchannelStateUpdate(subchannel, previousState, newState,
|
|
35304
|
+
onSubchannelStateUpdate(subchannel, previousState, newState, errorMessage5) {
|
|
35305
35305
|
var _a;
|
|
35306
35306
|
if ((_a = this.currentPick) === null || _a === void 0 ? void 0 : _a.realSubchannelEquals(subchannel)) {
|
|
35307
35307
|
if (newState !== connectivity_state_1.ConnectivityState.READY) {
|
|
@@ -35317,8 +35317,8 @@ var require_load_balancer_pick_first = __commonJS({
|
|
|
35317
35317
|
}
|
|
35318
35318
|
if (newState === connectivity_state_1.ConnectivityState.TRANSIENT_FAILURE) {
|
|
35319
35319
|
child.hasReportedTransientFailure = true;
|
|
35320
|
-
if (
|
|
35321
|
-
this.lastError =
|
|
35320
|
+
if (errorMessage5) {
|
|
35321
|
+
this.lastError = errorMessage5;
|
|
35322
35322
|
}
|
|
35323
35323
|
this.maybeEnterStickyTransientFailureMode();
|
|
35324
35324
|
if (index === this.currentSubchannelIndex) {
|
|
@@ -35383,10 +35383,10 @@ var require_load_balancer_pick_first = __commonJS({
|
|
|
35383
35383
|
clearTimeout(this.connectionDelayTimeout);
|
|
35384
35384
|
this.calculateAndReportNewState();
|
|
35385
35385
|
}
|
|
35386
|
-
updateState(newState, picker,
|
|
35386
|
+
updateState(newState, picker, errorMessage5) {
|
|
35387
35387
|
trace(connectivity_state_1.ConnectivityState[this.currentState] + " -> " + connectivity_state_1.ConnectivityState[newState]);
|
|
35388
35388
|
this.currentState = newState;
|
|
35389
|
-
this.channelControlHelper.updateState(newState, picker,
|
|
35389
|
+
this.channelControlHelper.updateState(newState, picker, errorMessage5);
|
|
35390
35390
|
}
|
|
35391
35391
|
resetSubchannelList() {
|
|
35392
35392
|
for (const child of this.children) {
|
|
@@ -35479,10 +35479,10 @@ var require_load_balancer_pick_first = __commonJS({
|
|
|
35479
35479
|
this.resolutionNote = resolutionNote;
|
|
35480
35480
|
this.latestState = connectivity_state_1.ConnectivityState.IDLE;
|
|
35481
35481
|
const childChannelControlHelper = (0, load_balancer_1.createChildChannelControlHelper)(channelControlHelper, {
|
|
35482
|
-
updateState: (connectivityState, picker,
|
|
35482
|
+
updateState: (connectivityState, picker, errorMessage5) => {
|
|
35483
35483
|
this.latestState = connectivityState;
|
|
35484
35484
|
this.latestPicker = picker;
|
|
35485
|
-
channelControlHelper.updateState(connectivityState, picker,
|
|
35485
|
+
channelControlHelper.updateState(connectivityState, picker, errorMessage5);
|
|
35486
35486
|
}
|
|
35487
35487
|
});
|
|
35488
35488
|
this.pickFirstBalancer = new PickFirstLoadBalancer(childChannelControlHelper);
|
|
@@ -35981,12 +35981,12 @@ var require_load_balancer_round_robin = __commonJS({
|
|
|
35981
35981
|
this.updatesPaused = false;
|
|
35982
35982
|
this.lastError = null;
|
|
35983
35983
|
this.childChannelControlHelper = (0, load_balancer_1.createChildChannelControlHelper)(channelControlHelper, {
|
|
35984
|
-
updateState: (connectivityState, picker,
|
|
35984
|
+
updateState: (connectivityState, picker, errorMessage5) => {
|
|
35985
35985
|
if (this.currentState === connectivity_state_1.ConnectivityState.READY && connectivityState !== connectivity_state_1.ConnectivityState.READY) {
|
|
35986
35986
|
this.channelControlHelper.requestReresolution();
|
|
35987
35987
|
}
|
|
35988
|
-
if (
|
|
35989
|
-
this.lastError =
|
|
35988
|
+
if (errorMessage5) {
|
|
35989
|
+
this.lastError = errorMessage5;
|
|
35990
35990
|
}
|
|
35991
35991
|
this.calculateAndUpdateState();
|
|
35992
35992
|
}
|
|
@@ -36016,10 +36016,10 @@ var require_load_balancer_round_robin = __commonJS({
|
|
|
36016
36016
|
} else if (this.countChildrenWithState(connectivity_state_1.ConnectivityState.CONNECTING) > 0) {
|
|
36017
36017
|
this.updateState(connectivity_state_1.ConnectivityState.CONNECTING, new picker_1.QueuePicker(this), null);
|
|
36018
36018
|
} else if (this.countChildrenWithState(connectivity_state_1.ConnectivityState.TRANSIENT_FAILURE) > 0) {
|
|
36019
|
-
const
|
|
36019
|
+
const errorMessage5 = `round_robin: No connection established. Last error: ${this.lastError}`;
|
|
36020
36020
|
this.updateState(connectivity_state_1.ConnectivityState.TRANSIENT_FAILURE, new picker_1.UnavailablePicker({
|
|
36021
|
-
details:
|
|
36022
|
-
}),
|
|
36021
|
+
details: errorMessage5
|
|
36022
|
+
}), errorMessage5);
|
|
36023
36023
|
} else {
|
|
36024
36024
|
this.updateState(connectivity_state_1.ConnectivityState.IDLE, new picker_1.QueuePicker(this), null);
|
|
36025
36025
|
}
|
|
@@ -36029,7 +36029,7 @@ var require_load_balancer_round_robin = __commonJS({
|
|
|
36029
36029
|
}
|
|
36030
36030
|
}
|
|
36031
36031
|
}
|
|
36032
|
-
updateState(newState, picker,
|
|
36032
|
+
updateState(newState, picker, errorMessage5) {
|
|
36033
36033
|
trace(connectivity_state_1.ConnectivityState[this.currentState] + " -> " + connectivity_state_1.ConnectivityState[newState]);
|
|
36034
36034
|
if (newState === connectivity_state_1.ConnectivityState.READY) {
|
|
36035
36035
|
this.currentReadyPicker = picker;
|
|
@@ -36037,7 +36037,7 @@ var require_load_balancer_round_robin = __commonJS({
|
|
|
36037
36037
|
this.currentReadyPicker = null;
|
|
36038
36038
|
}
|
|
36039
36039
|
this.currentState = newState;
|
|
36040
|
-
this.channelControlHelper.updateState(newState, picker,
|
|
36040
|
+
this.channelControlHelper.updateState(newState, picker, errorMessage5);
|
|
36041
36041
|
}
|
|
36042
36042
|
resetSubchannelList() {
|
|
36043
36043
|
for (const child of this.children) {
|
|
@@ -36059,8 +36059,8 @@ var require_load_balancer_round_robin = __commonJS({
|
|
|
36059
36059
|
const endpointList = rotateArray(maybeEndpointList.value, startIndex);
|
|
36060
36060
|
this.resetSubchannelList();
|
|
36061
36061
|
if (endpointList.length === 0) {
|
|
36062
|
-
const
|
|
36063
|
-
this.updateState(connectivity_state_1.ConnectivityState.TRANSIENT_FAILURE, new picker_1.UnavailablePicker({ details:
|
|
36062
|
+
const errorMessage5 = `No addresses resolved. Resolution note: ${resolutionNote}`;
|
|
36063
|
+
this.updateState(connectivity_state_1.ConnectivityState.TRANSIENT_FAILURE, new picker_1.UnavailablePicker({ details: errorMessage5 }), errorMessage5);
|
|
36064
36064
|
}
|
|
36065
36065
|
trace("Connect to endpoint list " + endpointList.map(subchannel_address_1.endpointToString));
|
|
36066
36066
|
this.updatesPaused = true;
|
|
@@ -36347,11 +36347,11 @@ var require_load_balancer_outlier_detection = __commonJS({
|
|
|
36347
36347
|
mapEntry === null || mapEntry === void 0 ? void 0 : mapEntry.subchannelWrappers.push(subchannelWrapper);
|
|
36348
36348
|
return subchannelWrapper;
|
|
36349
36349
|
},
|
|
36350
|
-
updateState: (connectivityState, picker,
|
|
36350
|
+
updateState: (connectivityState, picker, errorMessage5) => {
|
|
36351
36351
|
if (connectivityState === connectivity_state_1.ConnectivityState.READY) {
|
|
36352
|
-
channelControlHelper.updateState(connectivityState, new OutlierDetectionPicker(picker, this.isCountingEnabled()),
|
|
36352
|
+
channelControlHelper.updateState(connectivityState, new OutlierDetectionPicker(picker, this.isCountingEnabled()), errorMessage5);
|
|
36353
36353
|
} else {
|
|
36354
|
-
channelControlHelper.updateState(connectivityState, picker,
|
|
36354
|
+
channelControlHelper.updateState(connectivityState, picker, errorMessage5);
|
|
36355
36355
|
}
|
|
36356
36356
|
}
|
|
36357
36357
|
}));
|
|
@@ -36918,10 +36918,10 @@ var require_load_balancer_weighted_round_robin = __commonJS({
|
|
|
36918
36918
|
} else if (this.countChildrenWithState(connectivity_state_1.ConnectivityState.CONNECTING) > 0) {
|
|
36919
36919
|
this.updateState(connectivity_state_1.ConnectivityState.CONNECTING, new picker_1.QueuePicker(this), null);
|
|
36920
36920
|
} else if (this.countChildrenWithState(connectivity_state_1.ConnectivityState.TRANSIENT_FAILURE) > 0) {
|
|
36921
|
-
const
|
|
36921
|
+
const errorMessage5 = `weighted_round_robin: No connection established. Last error: ${this.lastError}`;
|
|
36922
36922
|
this.updateState(connectivity_state_1.ConnectivityState.TRANSIENT_FAILURE, new picker_1.UnavailablePicker({
|
|
36923
|
-
details:
|
|
36924
|
-
}),
|
|
36923
|
+
details: errorMessage5
|
|
36924
|
+
}), errorMessage5);
|
|
36925
36925
|
} else {
|
|
36926
36926
|
this.updateState(connectivity_state_1.ConnectivityState.IDLE, new picker_1.QueuePicker(this), null);
|
|
36927
36927
|
}
|
|
@@ -36931,10 +36931,10 @@ var require_load_balancer_weighted_round_robin = __commonJS({
|
|
|
36931
36931
|
}
|
|
36932
36932
|
}
|
|
36933
36933
|
}
|
|
36934
|
-
updateState(newState, picker,
|
|
36934
|
+
updateState(newState, picker, errorMessage5) {
|
|
36935
36935
|
trace(connectivity_state_1.ConnectivityState[this.currentState] + " -> " + connectivity_state_1.ConnectivityState[newState]);
|
|
36936
36936
|
this.currentState = newState;
|
|
36937
|
-
this.channelControlHelper.updateState(newState, picker,
|
|
36937
|
+
this.channelControlHelper.updateState(newState, picker, errorMessage5);
|
|
36938
36938
|
}
|
|
36939
36939
|
updateAddressList(maybeEndpointList, lbConfig, options, resolutionNote) {
|
|
36940
36940
|
var _a, _b;
|
|
@@ -36948,8 +36948,8 @@ var require_load_balancer_weighted_round_robin = __commonJS({
|
|
|
36948
36948
|
return true;
|
|
36949
36949
|
}
|
|
36950
36950
|
if (maybeEndpointList.value.length === 0) {
|
|
36951
|
-
const
|
|
36952
|
-
this.updateState(connectivity_state_1.ConnectivityState.TRANSIENT_FAILURE, new picker_1.UnavailablePicker({ details:
|
|
36951
|
+
const errorMessage5 = `No addresses resolved. Resolution note: ${resolutionNote}`;
|
|
36952
|
+
this.updateState(connectivity_state_1.ConnectivityState.TRANSIENT_FAILURE, new picker_1.UnavailablePicker({ details: errorMessage5 }), errorMessage5);
|
|
36953
36953
|
return false;
|
|
36954
36954
|
}
|
|
36955
36955
|
trace("Connect to endpoint list " + maybeEndpointList.value.map(subchannel_address_1.endpointToString));
|
|
@@ -36964,15 +36964,15 @@ var require_load_balancer_weighted_round_robin = __commonJS({
|
|
|
36964
36964
|
if (!entry) {
|
|
36965
36965
|
entry = {
|
|
36966
36966
|
child: new load_balancer_pick_first_1.LeafLoadBalancer(endpoint, (0, load_balancer_1.createChildChannelControlHelper)(this.channelControlHelper, {
|
|
36967
|
-
updateState: (connectivityState, picker,
|
|
36967
|
+
updateState: (connectivityState, picker, errorMessage5) => {
|
|
36968
36968
|
if (this.currentState === connectivity_state_1.ConnectivityState.READY && connectivityState !== connectivity_state_1.ConnectivityState.READY) {
|
|
36969
36969
|
this.channelControlHelper.requestReresolution();
|
|
36970
36970
|
}
|
|
36971
36971
|
if (connectivityState === connectivity_state_1.ConnectivityState.READY) {
|
|
36972
36972
|
entry.nonEmptySince = null;
|
|
36973
36973
|
}
|
|
36974
|
-
if (
|
|
36975
|
-
this.lastError =
|
|
36974
|
+
if (errorMessage5) {
|
|
36975
|
+
this.lastError = errorMessage5;
|
|
36976
36976
|
}
|
|
36977
36977
|
this.calculateAndUpdateState();
|
|
36978
36978
|
},
|
|
@@ -39503,7 +39503,7 @@ var require_DockerClient = __commonJS({
|
|
|
39503
39503
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
39504
39504
|
exports2.DockerClient = void 0;
|
|
39505
39505
|
var dockerode_1 = __importDefault(require_docker());
|
|
39506
|
-
var
|
|
39506
|
+
var DockerClient6 = class {
|
|
39507
39507
|
docker;
|
|
39508
39508
|
constructor(opts) {
|
|
39509
39509
|
this.docker = new dockerode_1.default(opts);
|
|
@@ -39740,9 +39740,15 @@ var require_DockerClient = __commonJS({
|
|
|
39740
39740
|
const result = await this.docker.pruneNetworks();
|
|
39741
39741
|
return { networksDeleted: result.NetworksDeleted || [] };
|
|
39742
39742
|
}
|
|
39743
|
-
async *streamEvents(filters) {
|
|
39743
|
+
async *streamEvents(filters, signal) {
|
|
39744
39744
|
const stream = await this.docker.getEvents({ filters });
|
|
39745
|
+
if (signal) {
|
|
39746
|
+
const onAbort = () => stream.destroy?.();
|
|
39747
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
39748
|
+
}
|
|
39745
39749
|
for await (const chunk of stream) {
|
|
39750
|
+
if (signal?.aborted)
|
|
39751
|
+
break;
|
|
39746
39752
|
const lines = chunk.toString("utf8").split("\n").filter(Boolean);
|
|
39747
39753
|
for (const line of lines) {
|
|
39748
39754
|
let raw;
|
|
@@ -39767,7 +39773,7 @@ var require_DockerClient = __commonJS({
|
|
|
39767
39773
|
dispose() {
|
|
39768
39774
|
}
|
|
39769
39775
|
};
|
|
39770
|
-
exports2.DockerClient =
|
|
39776
|
+
exports2.DockerClient = DockerClient6;
|
|
39771
39777
|
function mapResourceType(type) {
|
|
39772
39778
|
switch (type) {
|
|
39773
39779
|
case "container":
|
|
@@ -40087,7 +40093,7 @@ var require_StatsCollector = __commonJS({
|
|
|
40087
40093
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
40088
40094
|
exports2.StatsCollector = void 0;
|
|
40089
40095
|
var DEFAULT_MAX_SAMPLES = 60;
|
|
40090
|
-
var
|
|
40096
|
+
var StatsCollector3 = class {
|
|
40091
40097
|
histories = /* @__PURE__ */ new Map();
|
|
40092
40098
|
maxSamples;
|
|
40093
40099
|
constructor(maxSamples = DEFAULT_MAX_SAMPLES) {
|
|
@@ -40132,7 +40138,520 @@ var require_StatsCollector = __commonJS({
|
|
|
40132
40138
|
this.histories.clear();
|
|
40133
40139
|
}
|
|
40134
40140
|
};
|
|
40135
|
-
exports2.StatsCollector =
|
|
40141
|
+
exports2.StatsCollector = StatsCollector3;
|
|
40142
|
+
}
|
|
40143
|
+
});
|
|
40144
|
+
|
|
40145
|
+
// ../sidekick-docker-shared/dist/log/LogTokenizer.js
|
|
40146
|
+
var require_LogTokenizer = __commonJS({
|
|
40147
|
+
"../sidekick-docker-shared/dist/log/LogTokenizer.js"(exports2) {
|
|
40148
|
+
"use strict";
|
|
40149
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
40150
|
+
exports2.tokenizeLogLine = tokenizeLogLine2;
|
|
40151
|
+
var TOKEN_PATTERN = new RegExp([
|
|
40152
|
+
// HTTP status codes (3-digit, standalone)
|
|
40153
|
+
"(?<status>\\b[2345]\\d{2}\\b)",
|
|
40154
|
+
// HTTP methods
|
|
40155
|
+
"(?<method>\\b(?:GET|HEAD|OPTIONS|TRACE|PUT|POST|PATCH|DELETE)\\b)",
|
|
40156
|
+
// Severity keywords
|
|
40157
|
+
"(?<severity>\\b(?:FATAL|PANIC|ERROR|ERR|WARN|WARNING|INFO|DEBUG|TRACE)\\b)",
|
|
40158
|
+
// URLs (http/https)
|
|
40159
|
+
`(?<url>https?://[^\\s"'\\]}>)]+)`,
|
|
40160
|
+
// IP addresses (v4)
|
|
40161
|
+
"(?<ip>\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(?::\\d+)?\\b)",
|
|
40162
|
+
// ISO timestamps or common log timestamps
|
|
40163
|
+
"(?<timestamp>\\d{4}-\\d{2}-\\d{2}[T ]\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|[+-]\\d{2}:?\\d{2})?)",
|
|
40164
|
+
// JSON keys: "key":
|
|
40165
|
+
'(?<jsonkey>"[^"]{1,40}"(?=\\s*:))',
|
|
40166
|
+
// State keywords
|
|
40167
|
+
"(?<stateok>\\b(?:success|succeeded|healthy|active|enabled|connected|ready|complete|completed|started|up|online|resolved|passed|ok|done|alive)\\b)",
|
|
40168
|
+
"(?<statefail>\\b(?:fail|failed|failure|unhealthy|inactive|disabled|disconnected|timeout|refused|rejected|crashed|killed|stopped|unreachable|blocked|denied|broken)\\b)",
|
|
40169
|
+
// Unix-style paths
|
|
40170
|
+
"(?<path>(?:^|\\s)/[\\w./-]{2,})"
|
|
40171
|
+
].join("|"), "gi");
|
|
40172
|
+
function classifyStatus(code) {
|
|
40173
|
+
const n = parseInt(code, 10);
|
|
40174
|
+
if (n >= 200 && n < 300)
|
|
40175
|
+
return "http-status-2xx";
|
|
40176
|
+
if (n >= 300 && n < 400)
|
|
40177
|
+
return "http-status-3xx";
|
|
40178
|
+
if (n >= 400 && n < 500)
|
|
40179
|
+
return "http-status-4xx";
|
|
40180
|
+
return "http-status-5xx";
|
|
40181
|
+
}
|
|
40182
|
+
function classifySeverity(word) {
|
|
40183
|
+
const u = word.toUpperCase();
|
|
40184
|
+
if (u === "FATAL" || u === "PANIC" || u === "ERROR" || u === "ERR")
|
|
40185
|
+
return "severity-error";
|
|
40186
|
+
if (u === "WARN" || u === "WARNING")
|
|
40187
|
+
return "severity-warn";
|
|
40188
|
+
if (u === "INFO")
|
|
40189
|
+
return "severity-info";
|
|
40190
|
+
return "severity-debug";
|
|
40191
|
+
}
|
|
40192
|
+
function classifyMethod(method) {
|
|
40193
|
+
const u = method.toUpperCase();
|
|
40194
|
+
if (u === "GET" || u === "HEAD" || u === "OPTIONS" || u === "TRACE")
|
|
40195
|
+
return "http-method-safe";
|
|
40196
|
+
return "http-method-unsafe";
|
|
40197
|
+
}
|
|
40198
|
+
function tokenizeLogLine2(line) {
|
|
40199
|
+
if (!line)
|
|
40200
|
+
return [{ text: "", type: "plain" }];
|
|
40201
|
+
const tokens = [];
|
|
40202
|
+
let lastIndex = 0;
|
|
40203
|
+
TOKEN_PATTERN.lastIndex = 0;
|
|
40204
|
+
let match;
|
|
40205
|
+
while ((match = TOKEN_PATTERN.exec(line)) !== null) {
|
|
40206
|
+
if (match.index > lastIndex) {
|
|
40207
|
+
tokens.push({ text: line.slice(lastIndex, match.index), type: "plain" });
|
|
40208
|
+
}
|
|
40209
|
+
const groups = match.groups;
|
|
40210
|
+
let type = "plain";
|
|
40211
|
+
if (groups.status !== void 0)
|
|
40212
|
+
type = classifyStatus(groups.status);
|
|
40213
|
+
else if (groups.method !== void 0)
|
|
40214
|
+
type = classifyMethod(groups.method);
|
|
40215
|
+
else if (groups.severity !== void 0)
|
|
40216
|
+
type = classifySeverity(groups.severity);
|
|
40217
|
+
else if (groups.url !== void 0)
|
|
40218
|
+
type = "url";
|
|
40219
|
+
else if (groups.ip !== void 0)
|
|
40220
|
+
type = "ip-address";
|
|
40221
|
+
else if (groups.timestamp !== void 0)
|
|
40222
|
+
type = "timestamp";
|
|
40223
|
+
else if (groups.jsonkey !== void 0)
|
|
40224
|
+
type = "json-key";
|
|
40225
|
+
else if (groups.stateok !== void 0)
|
|
40226
|
+
type = "state-ok";
|
|
40227
|
+
else if (groups.statefail !== void 0)
|
|
40228
|
+
type = "state-fail";
|
|
40229
|
+
else if (groups.path !== void 0)
|
|
40230
|
+
type = "path";
|
|
40231
|
+
tokens.push({ text: match[0], type });
|
|
40232
|
+
lastIndex = match.index + match[0].length;
|
|
40233
|
+
}
|
|
40234
|
+
if (lastIndex < line.length) {
|
|
40235
|
+
tokens.push({ text: line.slice(lastIndex), type: "plain" });
|
|
40236
|
+
}
|
|
40237
|
+
return tokens;
|
|
40238
|
+
}
|
|
40239
|
+
}
|
|
40240
|
+
});
|
|
40241
|
+
|
|
40242
|
+
// ../sidekick-docker-shared/dist/log/LogFilter.js
|
|
40243
|
+
var require_LogFilter = __commonJS({
|
|
40244
|
+
"../sidekick-docker-shared/dist/log/LogFilter.js"(exports2) {
|
|
40245
|
+
"use strict";
|
|
40246
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
40247
|
+
exports2.exactMatch = exactMatch;
|
|
40248
|
+
exports2.fuzzyMatch = fuzzyMatch;
|
|
40249
|
+
exports2.filterLine = filterLine2;
|
|
40250
|
+
function exactMatch(line, query) {
|
|
40251
|
+
if (!query)
|
|
40252
|
+
return { matched: true, matches: [] };
|
|
40253
|
+
const lower = line.toLowerCase();
|
|
40254
|
+
const queryLower = query.toLowerCase();
|
|
40255
|
+
const matches = [];
|
|
40256
|
+
let pos = 0;
|
|
40257
|
+
while (pos < lower.length) {
|
|
40258
|
+
const idx = lower.indexOf(queryLower, pos);
|
|
40259
|
+
if (idx === -1)
|
|
40260
|
+
break;
|
|
40261
|
+
matches.push({ start: idx, length: queryLower.length });
|
|
40262
|
+
pos = idx + queryLower.length;
|
|
40263
|
+
}
|
|
40264
|
+
return { matched: matches.length > 0, matches };
|
|
40265
|
+
}
|
|
40266
|
+
function fuzzyMatch(line, query) {
|
|
40267
|
+
if (!query)
|
|
40268
|
+
return { matched: true, matches: [] };
|
|
40269
|
+
const words = query.split(/\s+/).filter((w) => w.length > 0);
|
|
40270
|
+
if (words.length === 0)
|
|
40271
|
+
return { matched: true, matches: [] };
|
|
40272
|
+
const lower = line.toLowerCase();
|
|
40273
|
+
const matches = [];
|
|
40274
|
+
for (const word of words) {
|
|
40275
|
+
const wordLower = word.toLowerCase();
|
|
40276
|
+
const idx = lower.indexOf(wordLower);
|
|
40277
|
+
if (idx === -1)
|
|
40278
|
+
return { matched: false, matches: [] };
|
|
40279
|
+
matches.push({ start: idx, length: wordLower.length });
|
|
40280
|
+
}
|
|
40281
|
+
matches.sort((a, b) => a.start - b.start);
|
|
40282
|
+
return { matched: true, matches };
|
|
40283
|
+
}
|
|
40284
|
+
function filterLine2(line, query, mode) {
|
|
40285
|
+
return mode === "exact" ? exactMatch(line, query) : fuzzyMatch(line, query);
|
|
40286
|
+
}
|
|
40287
|
+
}
|
|
40288
|
+
});
|
|
40289
|
+
|
|
40290
|
+
// ../sidekick-docker-shared/dist/log/LogAnalytics.js
|
|
40291
|
+
var require_LogAnalytics = __commonJS({
|
|
40292
|
+
"../sidekick-docker-shared/dist/log/LogAnalytics.js"(exports2) {
|
|
40293
|
+
"use strict";
|
|
40294
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
40295
|
+
exports2.LogAnalytics = void 0;
|
|
40296
|
+
exports2.detectSeverity = detectSeverity;
|
|
40297
|
+
var SEVERITY_PATTERN = /\b(FATAL|PANIC|ERROR|ERR|WARN|WARNING|INFO|DEBUG|TRACE)\b/i;
|
|
40298
|
+
function detectSeverity(message) {
|
|
40299
|
+
const match = message.substring(0, 200).match(SEVERITY_PATTERN);
|
|
40300
|
+
if (!match)
|
|
40301
|
+
return "other";
|
|
40302
|
+
const keyword = match[1].toUpperCase();
|
|
40303
|
+
if (keyword === "FATAL" || keyword === "PANIC" || keyword === "ERROR" || keyword === "ERR")
|
|
40304
|
+
return "error";
|
|
40305
|
+
if (keyword === "WARN" || keyword === "WARNING")
|
|
40306
|
+
return "warn";
|
|
40307
|
+
if (keyword === "INFO")
|
|
40308
|
+
return "info";
|
|
40309
|
+
return "debug";
|
|
40310
|
+
}
|
|
40311
|
+
var LogAnalytics2 = class {
|
|
40312
|
+
counts = { error: 0, warn: 0, info: 0, debug: 0, other: 0, total: 0 };
|
|
40313
|
+
/**
|
|
40314
|
+
* Classify a log message and update counts.
|
|
40315
|
+
*/
|
|
40316
|
+
push(message) {
|
|
40317
|
+
const severity = detectSeverity(message);
|
|
40318
|
+
this.counts[severity]++;
|
|
40319
|
+
this.counts.total++;
|
|
40320
|
+
return severity;
|
|
40321
|
+
}
|
|
40322
|
+
getCounts() {
|
|
40323
|
+
return { ...this.counts };
|
|
40324
|
+
}
|
|
40325
|
+
reset() {
|
|
40326
|
+
this.counts = { error: 0, warn: 0, info: 0, debug: 0, other: 0, total: 0 };
|
|
40327
|
+
}
|
|
40328
|
+
};
|
|
40329
|
+
exports2.LogAnalytics = LogAnalytics2;
|
|
40330
|
+
}
|
|
40331
|
+
});
|
|
40332
|
+
|
|
40333
|
+
// ../sidekick-docker-shared/dist/log/LogParser.js
|
|
40334
|
+
var require_LogParser = __commonJS({
|
|
40335
|
+
"../sidekick-docker-shared/dist/log/LogParser.js"(exports2) {
|
|
40336
|
+
"use strict";
|
|
40337
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
40338
|
+
exports2.detectFormat = detectFormat;
|
|
40339
|
+
exports2.parseLine = parseLine;
|
|
40340
|
+
var LogAnalytics_1 = require_LogAnalytics();
|
|
40341
|
+
var LEVEL_KEYS = ["level", "severity", "lvl", "log_level", "loglevel"];
|
|
40342
|
+
var MESSAGE_KEYS = ["msg", "message", "text", "body"];
|
|
40343
|
+
var TIMESTAMP_KEYS = ["time", "timestamp", "ts", "datetime", "date", "@timestamp", "t"];
|
|
40344
|
+
function normalizeLevel(value) {
|
|
40345
|
+
const upper = value.toUpperCase().trim();
|
|
40346
|
+
if (["FATAL", "PANIC", "ERROR", "ERR", "CRITICAL", "ALERT", "EMERGENCY", "EMERG"].includes(upper))
|
|
40347
|
+
return "error";
|
|
40348
|
+
if (["WARN", "WARNING"].includes(upper))
|
|
40349
|
+
return "warn";
|
|
40350
|
+
if (["INFO", "INFORMATION", "NOTICE"].includes(upper))
|
|
40351
|
+
return "info";
|
|
40352
|
+
if (["DEBUG", "TRACE", "VERBOSE"].includes(upper))
|
|
40353
|
+
return "debug";
|
|
40354
|
+
return null;
|
|
40355
|
+
}
|
|
40356
|
+
function findField(obj, keys) {
|
|
40357
|
+
for (const key of keys) {
|
|
40358
|
+
if (key in obj && obj[key] != null)
|
|
40359
|
+
return String(obj[key]);
|
|
40360
|
+
}
|
|
40361
|
+
return null;
|
|
40362
|
+
}
|
|
40363
|
+
function parseJson(line) {
|
|
40364
|
+
const trimmed = line.trim();
|
|
40365
|
+
if (!trimmed.startsWith("{"))
|
|
40366
|
+
return null;
|
|
40367
|
+
try {
|
|
40368
|
+
const obj = JSON.parse(trimmed);
|
|
40369
|
+
const levelValue = findField(obj, LEVEL_KEYS);
|
|
40370
|
+
const level = levelValue ? normalizeLevel(levelValue) : null;
|
|
40371
|
+
const message = findField(obj, MESSAGE_KEYS) ?? "";
|
|
40372
|
+
const timestamp = findField(obj, TIMESTAMP_KEYS);
|
|
40373
|
+
const extracted = /* @__PURE__ */ new Set([...LEVEL_KEYS, ...MESSAGE_KEYS, ...TIMESTAMP_KEYS]);
|
|
40374
|
+
const fields = {};
|
|
40375
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
40376
|
+
if (!extracted.has(k) && v != null) {
|
|
40377
|
+
fields[k] = typeof v === "string" ? v : JSON.stringify(v);
|
|
40378
|
+
}
|
|
40379
|
+
}
|
|
40380
|
+
return { format: "json", level, message, timestamp, fields, raw: line };
|
|
40381
|
+
} catch {
|
|
40382
|
+
return null;
|
|
40383
|
+
}
|
|
40384
|
+
}
|
|
40385
|
+
var LOGFMT_PAIR = /([a-zA-Z_][\w.-]*)=(?:"([^"]*)"|(\S*))/g;
|
|
40386
|
+
function parseLogfmt(line) {
|
|
40387
|
+
const pairs = [];
|
|
40388
|
+
let match;
|
|
40389
|
+
LOGFMT_PAIR.lastIndex = 0;
|
|
40390
|
+
while ((match = LOGFMT_PAIR.exec(line)) !== null) {
|
|
40391
|
+
pairs.push([match[1], match[2] ?? match[3]]);
|
|
40392
|
+
}
|
|
40393
|
+
if (pairs.length < 2)
|
|
40394
|
+
return null;
|
|
40395
|
+
const obj = {};
|
|
40396
|
+
for (const [k, v] of pairs)
|
|
40397
|
+
obj[k] = v;
|
|
40398
|
+
const levelValue = findField(obj, LEVEL_KEYS);
|
|
40399
|
+
const level = levelValue ? normalizeLevel(levelValue) : null;
|
|
40400
|
+
const message = findField(obj, MESSAGE_KEYS) ?? "";
|
|
40401
|
+
const timestamp = findField(obj, TIMESTAMP_KEYS);
|
|
40402
|
+
const extracted = /* @__PURE__ */ new Set([...LEVEL_KEYS, ...MESSAGE_KEYS, ...TIMESTAMP_KEYS]);
|
|
40403
|
+
const fields = {};
|
|
40404
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
40405
|
+
if (!extracted.has(k))
|
|
40406
|
+
fields[k] = v;
|
|
40407
|
+
}
|
|
40408
|
+
return { format: "logfmt", level, message, timestamp, fields, raw: line };
|
|
40409
|
+
}
|
|
40410
|
+
function detectFormat(line) {
|
|
40411
|
+
const trimmed = line.trim();
|
|
40412
|
+
if (trimmed.startsWith("{") && trimmed.endsWith("}"))
|
|
40413
|
+
return "json";
|
|
40414
|
+
LOGFMT_PAIR.lastIndex = 0;
|
|
40415
|
+
let pairCount = 0;
|
|
40416
|
+
while (LOGFMT_PAIR.exec(trimmed) !== null) {
|
|
40417
|
+
pairCount++;
|
|
40418
|
+
if (pairCount >= 2)
|
|
40419
|
+
return "logfmt";
|
|
40420
|
+
}
|
|
40421
|
+
return "plain";
|
|
40422
|
+
}
|
|
40423
|
+
function parseLine(line) {
|
|
40424
|
+
const jsonResult = parseJson(line);
|
|
40425
|
+
if (jsonResult)
|
|
40426
|
+
return jsonResult;
|
|
40427
|
+
const logfmtResult = parseLogfmt(line);
|
|
40428
|
+
if (logfmtResult)
|
|
40429
|
+
return logfmtResult;
|
|
40430
|
+
return {
|
|
40431
|
+
format: "plain",
|
|
40432
|
+
level: (0, LogAnalytics_1.detectSeverity)(line) !== "other" ? (0, LogAnalytics_1.detectSeverity)(line) : null,
|
|
40433
|
+
message: line,
|
|
40434
|
+
timestamp: null,
|
|
40435
|
+
fields: {},
|
|
40436
|
+
raw: line
|
|
40437
|
+
};
|
|
40438
|
+
}
|
|
40439
|
+
}
|
|
40440
|
+
});
|
|
40441
|
+
|
|
40442
|
+
// ../sidekick-docker-shared/dist/log/LogSeverityTimeSeries.js
|
|
40443
|
+
var require_LogSeverityTimeSeries = __commonJS({
|
|
40444
|
+
"../sidekick-docker-shared/dist/log/LogSeverityTimeSeries.js"(exports2) {
|
|
40445
|
+
"use strict";
|
|
40446
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
40447
|
+
exports2.LogSeverityTimeSeries = void 0;
|
|
40448
|
+
var DEFAULT_BUCKET_COUNT = 60;
|
|
40449
|
+
var BUCKET_DURATION_MS = 6e4;
|
|
40450
|
+
var LogSeverityTimeSeries2 = class {
|
|
40451
|
+
buckets = [];
|
|
40452
|
+
maxBuckets;
|
|
40453
|
+
bucketDuration;
|
|
40454
|
+
constructor(maxBuckets = DEFAULT_BUCKET_COUNT, bucketDuration = BUCKET_DURATION_MS) {
|
|
40455
|
+
this.maxBuckets = maxBuckets;
|
|
40456
|
+
this.bucketDuration = bucketDuration;
|
|
40457
|
+
}
|
|
40458
|
+
/**
|
|
40459
|
+
* Record a severity event at the current time.
|
|
40460
|
+
*/
|
|
40461
|
+
push(severity, now = Date.now()) {
|
|
40462
|
+
const bucketTs = Math.floor(now / this.bucketDuration) * this.bucketDuration;
|
|
40463
|
+
let bucket = this.buckets.length > 0 ? this.buckets[this.buckets.length - 1] : null;
|
|
40464
|
+
if (!bucket || bucket.timestamp !== bucketTs) {
|
|
40465
|
+
bucket = { timestamp: bucketTs, error: 0, warn: 0, info: 0, debug: 0, other: 0 };
|
|
40466
|
+
this.buckets.push(bucket);
|
|
40467
|
+
if (this.buckets.length > this.maxBuckets) {
|
|
40468
|
+
this.buckets.shift();
|
|
40469
|
+
}
|
|
40470
|
+
}
|
|
40471
|
+
bucket[severity]++;
|
|
40472
|
+
}
|
|
40473
|
+
/**
|
|
40474
|
+
* Get all buckets in chronological order.
|
|
40475
|
+
*/
|
|
40476
|
+
getBuckets() {
|
|
40477
|
+
return [...this.buckets];
|
|
40478
|
+
}
|
|
40479
|
+
/**
|
|
40480
|
+
* Get the dominant severity for each bucket (for coloring sparklines).
|
|
40481
|
+
*/
|
|
40482
|
+
getDominantSeries() {
|
|
40483
|
+
return this.buckets.map((b) => {
|
|
40484
|
+
const counts = [
|
|
40485
|
+
["error", b.error],
|
|
40486
|
+
["warn", b.warn],
|
|
40487
|
+
["info", b.info],
|
|
40488
|
+
["debug", b.debug],
|
|
40489
|
+
["other", b.other]
|
|
40490
|
+
];
|
|
40491
|
+
const total = counts.reduce((sum, [, c]) => sum + c, 0);
|
|
40492
|
+
const dominant = counts.reduce((best, curr) => curr[1] > best[1] ? curr : best);
|
|
40493
|
+
return { severity: dominant[0], total };
|
|
40494
|
+
});
|
|
40495
|
+
}
|
|
40496
|
+
/**
|
|
40497
|
+
* Get total counts per bucket (for sparkline height).
|
|
40498
|
+
*/
|
|
40499
|
+
getTotalSeries() {
|
|
40500
|
+
return this.buckets.map((b) => b.error + b.warn + b.info + b.debug + b.other);
|
|
40501
|
+
}
|
|
40502
|
+
reset() {
|
|
40503
|
+
this.buckets = [];
|
|
40504
|
+
}
|
|
40505
|
+
};
|
|
40506
|
+
exports2.LogSeverityTimeSeries = LogSeverityTimeSeries2;
|
|
40507
|
+
}
|
|
40508
|
+
});
|
|
40509
|
+
|
|
40510
|
+
// ../sidekick-docker-shared/dist/log/LogTemplateEngine.js
|
|
40511
|
+
var require_LogTemplateEngine = __commonJS({
|
|
40512
|
+
"../sidekick-docker-shared/dist/log/LogTemplateEngine.js"(exports2) {
|
|
40513
|
+
"use strict";
|
|
40514
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
40515
|
+
exports2.LogTemplateEngine = void 0;
|
|
40516
|
+
var VARIABLE_PATTERNS = [
|
|
40517
|
+
/^[0-9a-f]{8,}$/i,
|
|
40518
|
+
// hex strings (hashes, IDs)
|
|
40519
|
+
/^[0-9a-f]{8}-[0-9a-f]{4}-/i,
|
|
40520
|
+
// UUIDs
|
|
40521
|
+
/^\d+\.\d+\.\d+\.\d+/,
|
|
40522
|
+
// IP addresses
|
|
40523
|
+
/^\d{4}-\d{2}-\d{2}/,
|
|
40524
|
+
// dates
|
|
40525
|
+
/^\d+$/,
|
|
40526
|
+
// pure numbers
|
|
40527
|
+
/^\/[\w/.-]+$/,
|
|
40528
|
+
// paths
|
|
40529
|
+
/^https?:\/\//,
|
|
40530
|
+
// URLs
|
|
40531
|
+
/^"[^"]*"$/,
|
|
40532
|
+
// quoted strings
|
|
40533
|
+
/^'[^']*'$/
|
|
40534
|
+
// single-quoted strings
|
|
40535
|
+
];
|
|
40536
|
+
function isVariable(token) {
|
|
40537
|
+
return VARIABLE_PATTERNS.some((p) => p.test(token));
|
|
40538
|
+
}
|
|
40539
|
+
var LogTemplateEngine2 = class {
|
|
40540
|
+
// Group templates by token count for efficient lookup
|
|
40541
|
+
groups = /* @__PURE__ */ new Map();
|
|
40542
|
+
totalLines = 0;
|
|
40543
|
+
/**
|
|
40544
|
+
* Process a log line and update templates.
|
|
40545
|
+
*/
|
|
40546
|
+
push(line) {
|
|
40547
|
+
this.totalLines++;
|
|
40548
|
+
const tokens = tokenize3(line);
|
|
40549
|
+
if (tokens.length === 0)
|
|
40550
|
+
return;
|
|
40551
|
+
const groups = this.groups.get(tokens.length);
|
|
40552
|
+
if (!groups) {
|
|
40553
|
+
this.groups.set(tokens.length, [{ tokens: tokens.map((t) => isVariable(t) ? "<*>" : t), count: 1 }]);
|
|
40554
|
+
return;
|
|
40555
|
+
}
|
|
40556
|
+
let bestMatch = null;
|
|
40557
|
+
let bestScore = 0;
|
|
40558
|
+
for (const group of groups) {
|
|
40559
|
+
let matching = 0;
|
|
40560
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
40561
|
+
if (group.tokens[i] === "<*>" || group.tokens[i] === tokens[i]) {
|
|
40562
|
+
matching++;
|
|
40563
|
+
}
|
|
40564
|
+
}
|
|
40565
|
+
const score = matching / tokens.length;
|
|
40566
|
+
if (score > bestScore && score >= 0.5) {
|
|
40567
|
+
bestScore = score;
|
|
40568
|
+
bestMatch = group;
|
|
40569
|
+
}
|
|
40570
|
+
}
|
|
40571
|
+
if (bestMatch) {
|
|
40572
|
+
bestMatch.count++;
|
|
40573
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
40574
|
+
if (bestMatch.tokens[i] !== "<*>" && bestMatch.tokens[i] !== tokens[i]) {
|
|
40575
|
+
bestMatch.tokens[i] = "<*>";
|
|
40576
|
+
}
|
|
40577
|
+
}
|
|
40578
|
+
} else {
|
|
40579
|
+
groups.push({ tokens: tokens.map((t) => isVariable(t) ? "<*>" : t), count: 1 });
|
|
40580
|
+
}
|
|
40581
|
+
}
|
|
40582
|
+
/**
|
|
40583
|
+
* Get all templates sorted by frequency (most common first).
|
|
40584
|
+
*/
|
|
40585
|
+
getTemplates(limit = 20) {
|
|
40586
|
+
const all = [];
|
|
40587
|
+
for (const [tokenCount, groups] of this.groups) {
|
|
40588
|
+
for (const group of groups) {
|
|
40589
|
+
all.push({
|
|
40590
|
+
pattern: group.tokens.join(" "),
|
|
40591
|
+
count: group.count,
|
|
40592
|
+
tokenCount
|
|
40593
|
+
});
|
|
40594
|
+
}
|
|
40595
|
+
}
|
|
40596
|
+
all.sort((a, b) => b.count - a.count);
|
|
40597
|
+
return all.slice(0, limit);
|
|
40598
|
+
}
|
|
40599
|
+
getTotalLines() {
|
|
40600
|
+
return this.totalLines;
|
|
40601
|
+
}
|
|
40602
|
+
reset() {
|
|
40603
|
+
this.groups.clear();
|
|
40604
|
+
this.totalLines = 0;
|
|
40605
|
+
}
|
|
40606
|
+
};
|
|
40607
|
+
exports2.LogTemplateEngine = LogTemplateEngine2;
|
|
40608
|
+
function tokenize3(line) {
|
|
40609
|
+
return line.split(/\s+/).filter((t) => t.length > 0);
|
|
40610
|
+
}
|
|
40611
|
+
}
|
|
40612
|
+
});
|
|
40613
|
+
|
|
40614
|
+
// ../sidekick-docker-shared/dist/reconnect.js
|
|
40615
|
+
var require_reconnect = __commonJS({
|
|
40616
|
+
"../sidekick-docker-shared/dist/reconnect.js"(exports2) {
|
|
40617
|
+
"use strict";
|
|
40618
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
40619
|
+
exports2.ReconnectScheduler = exports2.MAX_RECONNECT_ATTEMPTS = exports2.MAX_RECONNECT_DELAY = exports2.INITIAL_RECONNECT_DELAY = void 0;
|
|
40620
|
+
exports2.INITIAL_RECONNECT_DELAY = 2e3;
|
|
40621
|
+
exports2.MAX_RECONNECT_DELAY = 3e4;
|
|
40622
|
+
exports2.MAX_RECONNECT_ATTEMPTS = 10;
|
|
40623
|
+
var ReconnectScheduler4 = class {
|
|
40624
|
+
timer = null;
|
|
40625
|
+
attempts = 0;
|
|
40626
|
+
delay = exports2.INITIAL_RECONNECT_DELAY;
|
|
40627
|
+
/** Schedule a reconnect callback with exponential backoff. Returns false if max attempts reached. */
|
|
40628
|
+
schedule(callback) {
|
|
40629
|
+
if (this.attempts >= exports2.MAX_RECONNECT_ATTEMPTS) {
|
|
40630
|
+
return false;
|
|
40631
|
+
}
|
|
40632
|
+
this.clear();
|
|
40633
|
+
this.timer = setTimeout(() => {
|
|
40634
|
+
this.timer = null;
|
|
40635
|
+
this.attempts++;
|
|
40636
|
+
this.delay = Math.min(this.delay * 2, exports2.MAX_RECONNECT_DELAY);
|
|
40637
|
+
callback();
|
|
40638
|
+
}, this.delay);
|
|
40639
|
+
return true;
|
|
40640
|
+
}
|
|
40641
|
+
/** Clear any pending reconnect timer. */
|
|
40642
|
+
clear() {
|
|
40643
|
+
if (this.timer) {
|
|
40644
|
+
clearTimeout(this.timer);
|
|
40645
|
+
this.timer = null;
|
|
40646
|
+
}
|
|
40647
|
+
}
|
|
40648
|
+
/** Reset backoff state (call after a successful stream). */
|
|
40649
|
+
reset() {
|
|
40650
|
+
this.attempts = 0;
|
|
40651
|
+
this.delay = exports2.INITIAL_RECONNECT_DELAY;
|
|
40652
|
+
}
|
|
40653
|
+
};
|
|
40654
|
+
exports2.ReconnectScheduler = ReconnectScheduler4;
|
|
40136
40655
|
}
|
|
40137
40656
|
});
|
|
40138
40657
|
|
|
@@ -40142,13 +40661,13 @@ var require_EventWatcher = __commonJS({
|
|
|
40142
40661
|
"use strict";
|
|
40143
40662
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
40144
40663
|
exports2.EventWatcher = void 0;
|
|
40664
|
+
var reconnect_1 = require_reconnect();
|
|
40145
40665
|
var EventWatcher2 = class {
|
|
40146
40666
|
client;
|
|
40147
40667
|
callbacks;
|
|
40148
40668
|
running = false;
|
|
40149
40669
|
abortController = null;
|
|
40150
|
-
reconnectDelay =
|
|
40151
|
-
maxReconnectDelay = 3e4;
|
|
40670
|
+
reconnectDelay = reconnect_1.INITIAL_RECONNECT_DELAY;
|
|
40152
40671
|
constructor(client, callbacks) {
|
|
40153
40672
|
this.client = client;
|
|
40154
40673
|
this.callbacks = callbacks;
|
|
@@ -40157,7 +40676,7 @@ var require_EventWatcher = __commonJS({
|
|
|
40157
40676
|
if (this.running)
|
|
40158
40677
|
return;
|
|
40159
40678
|
this.running = true;
|
|
40160
|
-
this.reconnectDelay =
|
|
40679
|
+
this.reconnectDelay = reconnect_1.INITIAL_RECONNECT_DELAY;
|
|
40161
40680
|
this.watch();
|
|
40162
40681
|
}
|
|
40163
40682
|
stop() {
|
|
@@ -40172,12 +40691,12 @@ var require_EventWatcher = __commonJS({
|
|
|
40172
40691
|
while (this.running) {
|
|
40173
40692
|
try {
|
|
40174
40693
|
this.abortController = new AbortController();
|
|
40175
|
-
for await (const event of this.client.streamEvents()) {
|
|
40694
|
+
for await (const event of this.client.streamEvents(void 0, this.abortController.signal)) {
|
|
40176
40695
|
if (!this.running)
|
|
40177
40696
|
break;
|
|
40178
40697
|
this.callbacks.onEvent(event);
|
|
40179
40698
|
}
|
|
40180
|
-
this.reconnectDelay =
|
|
40699
|
+
this.reconnectDelay = reconnect_1.INITIAL_RECONNECT_DELAY;
|
|
40181
40700
|
} catch (err) {
|
|
40182
40701
|
if (!this.running)
|
|
40183
40702
|
break;
|
|
@@ -40186,15 +40705,22 @@ var require_EventWatcher = __commonJS({
|
|
|
40186
40705
|
if (!this.running)
|
|
40187
40706
|
break;
|
|
40188
40707
|
this.callbacks.onReconnect?.();
|
|
40189
|
-
await
|
|
40190
|
-
this.reconnectDelay = Math.min(this.reconnectDelay * 2,
|
|
40191
|
-
}
|
|
40708
|
+
await this.cancellableSleep(this.reconnectDelay);
|
|
40709
|
+
this.reconnectDelay = Math.min(this.reconnectDelay * 2, reconnect_1.MAX_RECONNECT_DELAY);
|
|
40710
|
+
}
|
|
40711
|
+
}
|
|
40712
|
+
/** Sleep that resolves early when stop() is called. */
|
|
40713
|
+
cancellableSleep(ms) {
|
|
40714
|
+
return new Promise((resolve) => {
|
|
40715
|
+
const timer = setTimeout(resolve, ms);
|
|
40716
|
+
this.abortController?.signal.addEventListener("abort", () => {
|
|
40717
|
+
clearTimeout(timer);
|
|
40718
|
+
resolve();
|
|
40719
|
+
}, { once: true });
|
|
40720
|
+
});
|
|
40192
40721
|
}
|
|
40193
40722
|
};
|
|
40194
40723
|
exports2.EventWatcher = EventWatcher2;
|
|
40195
|
-
function sleep(ms) {
|
|
40196
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
40197
|
-
}
|
|
40198
40724
|
}
|
|
40199
40725
|
});
|
|
40200
40726
|
|
|
@@ -40279,6 +40805,18 @@ var require_formatters = __commonJS({
|
|
|
40279
40805
|
}
|
|
40280
40806
|
});
|
|
40281
40807
|
|
|
40808
|
+
// ../sidekick-docker-shared/dist/errors.js
|
|
40809
|
+
var require_errors2 = __commonJS({
|
|
40810
|
+
"../sidekick-docker-shared/dist/errors.js"(exports2) {
|
|
40811
|
+
"use strict";
|
|
40812
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
40813
|
+
exports2.errorMessage = errorMessage5;
|
|
40814
|
+
function errorMessage5(err) {
|
|
40815
|
+
return err instanceof Error ? err.message : String(err);
|
|
40816
|
+
}
|
|
40817
|
+
}
|
|
40818
|
+
});
|
|
40819
|
+
|
|
40282
40820
|
// ../sidekick-docker-shared/dist/branding.js
|
|
40283
40821
|
var require_branding = __commonJS({
|
|
40284
40822
|
"../sidekick-docker-shared/dist/branding.js"(exports2) {
|
|
@@ -41003,7 +41541,7 @@ var require_dist = __commonJS({
|
|
|
41003
41541
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding(exports3, m, p);
|
|
41004
41542
|
};
|
|
41005
41543
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
41006
|
-
exports2.getRandomPhrase = exports2.BRAND_COLOR_ANSI_RESET = exports2.BRAND_COLOR_ANSI = exports2.BRAND_COLOR_HEX = exports2.BRAND_TAGLINE = exports2.BRAND_INLINE = exports2.stateColor = exports2.truncate = exports2.stateIcon = exports2.formatPorts = exports2.formatMemory = exports2.formatCpu = exports2.formatBytes = exports2.EventWatcher = exports2.StatsCollector = exports2.ComposeFileReader = exports2.ComposeClient = exports2.ComposeDetector = exports2.DockerClient = void 0;
|
|
41544
|
+
exports2.getRandomPhrase = exports2.BRAND_COLOR_ANSI_RESET = exports2.BRAND_COLOR_ANSI = exports2.BRAND_COLOR_HEX = exports2.BRAND_TAGLINE = exports2.BRAND_INLINE = exports2.MAX_LOG_LINES = exports2.errorMessage = exports2.MAX_RECONNECT_ATTEMPTS = exports2.MAX_RECONNECT_DELAY = exports2.INITIAL_RECONNECT_DELAY = exports2.ReconnectScheduler = exports2.stateColor = exports2.truncate = exports2.stateIcon = exports2.formatPorts = exports2.formatMemory = exports2.formatCpu = exports2.formatBytes = exports2.EventWatcher = exports2.LogTemplateEngine = exports2.LogSeverityTimeSeries = exports2.parseLine = exports2.detectFormat = exports2.detectSeverity = exports2.LogAnalytics = exports2.filterLine = exports2.fuzzyMatch = exports2.exactMatch = exports2.tokenizeLogLine = exports2.StatsCollector = exports2.ComposeFileReader = exports2.ComposeClient = exports2.ComposeDetector = exports2.DockerClient = void 0;
|
|
41007
41545
|
__exportStar(require_types(), exports2);
|
|
41008
41546
|
var DockerClient_1 = require_DockerClient();
|
|
41009
41547
|
Object.defineProperty(exports2, "DockerClient", { enumerable: true, get: function() {
|
|
@@ -41025,6 +41563,42 @@ var require_dist = __commonJS({
|
|
|
41025
41563
|
Object.defineProperty(exports2, "StatsCollector", { enumerable: true, get: function() {
|
|
41026
41564
|
return StatsCollector_1.StatsCollector;
|
|
41027
41565
|
} });
|
|
41566
|
+
var LogTokenizer_1 = require_LogTokenizer();
|
|
41567
|
+
Object.defineProperty(exports2, "tokenizeLogLine", { enumerable: true, get: function() {
|
|
41568
|
+
return LogTokenizer_1.tokenizeLogLine;
|
|
41569
|
+
} });
|
|
41570
|
+
var LogFilter_1 = require_LogFilter();
|
|
41571
|
+
Object.defineProperty(exports2, "exactMatch", { enumerable: true, get: function() {
|
|
41572
|
+
return LogFilter_1.exactMatch;
|
|
41573
|
+
} });
|
|
41574
|
+
Object.defineProperty(exports2, "fuzzyMatch", { enumerable: true, get: function() {
|
|
41575
|
+
return LogFilter_1.fuzzyMatch;
|
|
41576
|
+
} });
|
|
41577
|
+
Object.defineProperty(exports2, "filterLine", { enumerable: true, get: function() {
|
|
41578
|
+
return LogFilter_1.filterLine;
|
|
41579
|
+
} });
|
|
41580
|
+
var LogAnalytics_1 = require_LogAnalytics();
|
|
41581
|
+
Object.defineProperty(exports2, "LogAnalytics", { enumerable: true, get: function() {
|
|
41582
|
+
return LogAnalytics_1.LogAnalytics;
|
|
41583
|
+
} });
|
|
41584
|
+
Object.defineProperty(exports2, "detectSeverity", { enumerable: true, get: function() {
|
|
41585
|
+
return LogAnalytics_1.detectSeverity;
|
|
41586
|
+
} });
|
|
41587
|
+
var LogParser_1 = require_LogParser();
|
|
41588
|
+
Object.defineProperty(exports2, "detectFormat", { enumerable: true, get: function() {
|
|
41589
|
+
return LogParser_1.detectFormat;
|
|
41590
|
+
} });
|
|
41591
|
+
Object.defineProperty(exports2, "parseLine", { enumerable: true, get: function() {
|
|
41592
|
+
return LogParser_1.parseLine;
|
|
41593
|
+
} });
|
|
41594
|
+
var LogSeverityTimeSeries_1 = require_LogSeverityTimeSeries();
|
|
41595
|
+
Object.defineProperty(exports2, "LogSeverityTimeSeries", { enumerable: true, get: function() {
|
|
41596
|
+
return LogSeverityTimeSeries_1.LogSeverityTimeSeries;
|
|
41597
|
+
} });
|
|
41598
|
+
var LogTemplateEngine_1 = require_LogTemplateEngine();
|
|
41599
|
+
Object.defineProperty(exports2, "LogTemplateEngine", { enumerable: true, get: function() {
|
|
41600
|
+
return LogTemplateEngine_1.LogTemplateEngine;
|
|
41601
|
+
} });
|
|
41028
41602
|
var EventWatcher_1 = require_EventWatcher();
|
|
41029
41603
|
Object.defineProperty(exports2, "EventWatcher", { enumerable: true, get: function() {
|
|
41030
41604
|
return EventWatcher_1.EventWatcher;
|
|
@@ -41051,6 +41625,24 @@ var require_dist = __commonJS({
|
|
|
41051
41625
|
Object.defineProperty(exports2, "stateColor", { enumerable: true, get: function() {
|
|
41052
41626
|
return formatters_1.stateColor;
|
|
41053
41627
|
} });
|
|
41628
|
+
var reconnect_1 = require_reconnect();
|
|
41629
|
+
Object.defineProperty(exports2, "ReconnectScheduler", { enumerable: true, get: function() {
|
|
41630
|
+
return reconnect_1.ReconnectScheduler;
|
|
41631
|
+
} });
|
|
41632
|
+
Object.defineProperty(exports2, "INITIAL_RECONNECT_DELAY", { enumerable: true, get: function() {
|
|
41633
|
+
return reconnect_1.INITIAL_RECONNECT_DELAY;
|
|
41634
|
+
} });
|
|
41635
|
+
Object.defineProperty(exports2, "MAX_RECONNECT_DELAY", { enumerable: true, get: function() {
|
|
41636
|
+
return reconnect_1.MAX_RECONNECT_DELAY;
|
|
41637
|
+
} });
|
|
41638
|
+
Object.defineProperty(exports2, "MAX_RECONNECT_ATTEMPTS", { enumerable: true, get: function() {
|
|
41639
|
+
return reconnect_1.MAX_RECONNECT_ATTEMPTS;
|
|
41640
|
+
} });
|
|
41641
|
+
var errors_1 = require_errors2();
|
|
41642
|
+
Object.defineProperty(exports2, "errorMessage", { enumerable: true, get: function() {
|
|
41643
|
+
return errors_1.errorMessage;
|
|
41644
|
+
} });
|
|
41645
|
+
exports2.MAX_LOG_LINES = 1e3;
|
|
41054
41646
|
var branding_1 = require_branding();
|
|
41055
41647
|
Object.defineProperty(exports2, "BRAND_INLINE", { enumerable: true, get: function() {
|
|
41056
41648
|
return branding_1.BRAND_INLINE;
|
|
@@ -77369,8 +77961,8 @@ var {
|
|
|
77369
77961
|
} = import_index.default;
|
|
77370
77962
|
|
|
77371
77963
|
// src/commands/dashboard.ts
|
|
77372
|
-
var
|
|
77373
|
-
var
|
|
77964
|
+
var import_react37 = __toESM(require_react(), 1);
|
|
77965
|
+
var import_sidekick_docker_shared13 = __toESM(require_dist(), 1);
|
|
77374
77966
|
import { spawnSync } from "child_process";
|
|
77375
77967
|
|
|
77376
77968
|
// src/dashboard/DockerState.ts
|
|
@@ -77426,8 +78018,7 @@ var DockerState = class {
|
|
|
77426
78018
|
case "image":
|
|
77427
78019
|
case "volume":
|
|
77428
78020
|
case "network":
|
|
77429
|
-
this.refresh().catch(() =>
|
|
77430
|
-
});
|
|
78021
|
+
this.refresh().catch((e) => console.debug("refresh failed:", e));
|
|
77431
78022
|
break;
|
|
77432
78023
|
}
|
|
77433
78024
|
}
|
|
@@ -77439,11 +78030,10 @@ var DockerState = class {
|
|
|
77439
78030
|
case "unpause": {
|
|
77440
78031
|
const existing = this.containers.find((c) => c.id === resourceId);
|
|
77441
78032
|
if (existing) {
|
|
77442
|
-
existing.state =
|
|
78033
|
+
existing.state = "running";
|
|
77443
78034
|
existing.status = "Up just now";
|
|
77444
78035
|
}
|
|
77445
|
-
this.refresh().catch(() =>
|
|
77446
|
-
});
|
|
78036
|
+
this.refresh().catch((e) => console.debug("refresh failed:", e));
|
|
77447
78037
|
break;
|
|
77448
78038
|
}
|
|
77449
78039
|
case "stop":
|
|
@@ -77467,13 +78057,11 @@ var DockerState = class {
|
|
|
77467
78057
|
this.statsCollector.remove(resourceId);
|
|
77468
78058
|
break;
|
|
77469
78059
|
case "create":
|
|
77470
|
-
this.refresh().catch(() =>
|
|
77471
|
-
});
|
|
78060
|
+
this.refresh().catch((e) => console.debug("refresh failed:", e));
|
|
77472
78061
|
break;
|
|
77473
78062
|
default:
|
|
77474
78063
|
if (name) {
|
|
77475
|
-
this.refresh().catch(() =>
|
|
77476
|
-
});
|
|
78064
|
+
this.refresh().catch((e) => console.debug("refresh failed:", e));
|
|
77477
78065
|
}
|
|
77478
78066
|
break;
|
|
77479
78067
|
}
|
|
@@ -77484,7 +78072,7 @@ var DockerState = class {
|
|
|
77484
78072
|
}
|
|
77485
78073
|
appendLog(entry) {
|
|
77486
78074
|
this.selectedLogs.push(entry);
|
|
77487
|
-
if (this.selectedLogs.length >
|
|
78075
|
+
if (this.selectedLogs.length > import_sidekick_docker_shared.MAX_LOG_LINES) {
|
|
77488
78076
|
this.selectedLogs.shift();
|
|
77489
78077
|
}
|
|
77490
78078
|
}
|
|
@@ -77493,7 +78081,7 @@ var DockerState = class {
|
|
|
77493
78081
|
}
|
|
77494
78082
|
appendComposeLog(entry) {
|
|
77495
78083
|
this.selectedComposeLogs.push(entry);
|
|
77496
|
-
if (this.selectedComposeLogs.length >
|
|
78084
|
+
if (this.selectedComposeLogs.length > import_sidekick_docker_shared.MAX_LOG_LINES) {
|
|
77497
78085
|
this.selectedComposeLogs.shift();
|
|
77498
78086
|
}
|
|
77499
78087
|
}
|
|
@@ -77521,13 +78109,27 @@ var DockerState = class {
|
|
|
77521
78109
|
selectedContainerLogs: [...this.selectedLogs],
|
|
77522
78110
|
selectedComposeLogs: [...this.selectedComposeLogs],
|
|
77523
78111
|
lastRefresh: this.lastRefresh,
|
|
77524
|
-
daemonConnected: this.daemonConnected
|
|
78112
|
+
daemonConnected: this.daemonConnected,
|
|
78113
|
+
logFilterString: "",
|
|
78114
|
+
logFilterMode: "exact",
|
|
78115
|
+
logSeverityCounts: null,
|
|
78116
|
+
logSeverityTimeSeries: [],
|
|
78117
|
+
logTemplates: []
|
|
77525
78118
|
};
|
|
77526
78119
|
}
|
|
77527
78120
|
};
|
|
77528
78121
|
|
|
78122
|
+
// src/dashboard/panels/ContainersPanel.ts
|
|
78123
|
+
var import_sidekick_docker_shared4 = __toESM(require_dist(), 1);
|
|
78124
|
+
|
|
78125
|
+
// src/dashboard/panels/types.ts
|
|
78126
|
+
var defaultOnError = (msg) => {
|
|
78127
|
+
console.debug(msg);
|
|
78128
|
+
};
|
|
78129
|
+
|
|
77529
78130
|
// src/formatters.ts
|
|
77530
78131
|
var import_sidekick_docker_shared2 = __toESM(require_dist(), 1);
|
|
78132
|
+
var import_sidekick_docker_shared3 = __toESM(require_dist(), 1);
|
|
77531
78133
|
function formatUptime(status) {
|
|
77532
78134
|
return status;
|
|
77533
78135
|
}
|
|
@@ -77574,6 +78176,23 @@ function sparkline(values, width = 40) {
|
|
|
77574
78176
|
return bars[idx];
|
|
77575
78177
|
}).join("");
|
|
77576
78178
|
}
|
|
78179
|
+
var SEVERITY_COLORS = {
|
|
78180
|
+
error: (s) => `\x1B[31m${s}\x1B[39m`,
|
|
78181
|
+
warn: (s) => `\x1B[33m${s}\x1B[39m`,
|
|
78182
|
+
info: (s) => `\x1B[38;2;43;76;126m${s}\x1B[39m`,
|
|
78183
|
+
debug: (s) => `\x1B[90m${s}\x1B[39m`,
|
|
78184
|
+
other: (s) => `\x1B[90m${s}\x1B[39m`
|
|
78185
|
+
};
|
|
78186
|
+
function severitySparkline(series, width = 40) {
|
|
78187
|
+
if (series.length === 0) return "";
|
|
78188
|
+
const recent = series.slice(-width);
|
|
78189
|
+
const max = Math.max(...recent.map((s) => s.total), 1);
|
|
78190
|
+
const bars = "\u2581\u2582\u2583\u2584\u2585\u2586\u2587\u2588";
|
|
78191
|
+
return recent.map((s) => {
|
|
78192
|
+
const idx = Math.min(Math.floor(s.total / max * (bars.length - 1)), bars.length - 1);
|
|
78193
|
+
return SEVERITY_COLORS[s.severity](bars[idx]);
|
|
78194
|
+
}).join("");
|
|
78195
|
+
}
|
|
77577
78196
|
var ansi = {
|
|
77578
78197
|
gray: (s) => `\x1B[90m${s}\x1B[39m`,
|
|
77579
78198
|
red: (s) => `\x1B[31m${s}\x1B[39m`,
|
|
@@ -77583,26 +78202,64 @@ var ansi = {
|
|
|
77583
78202
|
dim: (s) => `\x1B[2m${s}\x1B[22m`,
|
|
77584
78203
|
bold: (s) => `\x1B[1m${s}\x1B[22m`
|
|
77585
78204
|
};
|
|
77586
|
-
|
|
77587
|
-
|
|
77588
|
-
|
|
77589
|
-
|
|
77590
|
-
|
|
77591
|
-
|
|
77592
|
-
|
|
77593
|
-
|
|
78205
|
+
var TOKEN_COLORS = {
|
|
78206
|
+
"severity-error": ansi.red,
|
|
78207
|
+
"severity-warn": ansi.yellow,
|
|
78208
|
+
"severity-info": ansi.brand,
|
|
78209
|
+
"severity-debug": ansi.gray,
|
|
78210
|
+
"http-method-safe": ansi.green,
|
|
78211
|
+
"http-method-unsafe": ansi.yellow,
|
|
78212
|
+
"http-status-2xx": ansi.green,
|
|
78213
|
+
"http-status-3xx": ansi.brand,
|
|
78214
|
+
"http-status-4xx": ansi.yellow,
|
|
78215
|
+
"http-status-5xx": ansi.red,
|
|
78216
|
+
"url": ansi.brand,
|
|
78217
|
+
"ip-address": ansi.dim,
|
|
78218
|
+
"timestamp": (s) => ansi.dim(ansi.gray(s)),
|
|
78219
|
+
"json-key": ansi.brand,
|
|
78220
|
+
"state-ok": ansi.green,
|
|
78221
|
+
"state-fail": ansi.red,
|
|
78222
|
+
"path": ansi.dim,
|
|
78223
|
+
"number": null,
|
|
78224
|
+
"plain": null
|
|
78225
|
+
};
|
|
78226
|
+
function colorizeTokens(message) {
|
|
78227
|
+
const tokens = (0, import_sidekick_docker_shared2.tokenizeLogLine)(message);
|
|
78228
|
+
return tokens.map((t) => {
|
|
78229
|
+
const colorFn = TOKEN_COLORS[t.type];
|
|
78230
|
+
return colorFn ? colorFn(t.text) : t.text;
|
|
78231
|
+
}).join("");
|
|
77594
78232
|
}
|
|
77595
|
-
function colorizeLogEntry(entry) {
|
|
78233
|
+
function colorizeLogEntry(entry, filterMatches) {
|
|
77596
78234
|
const ts = entry.timestamp ? entry.timestamp.toISOString().substring(11, 23) : "";
|
|
77597
78235
|
const tsColored = ts ? ansi.dim(ansi.gray(ts)) + " " : "";
|
|
77598
78236
|
if (entry.stream === "stderr") {
|
|
77599
|
-
|
|
78237
|
+
const msg = filterMatches ? highlightMatches(entry.message, filterMatches, ansi.red) : ansi.red(entry.message);
|
|
78238
|
+
return tsColored + msg;
|
|
77600
78239
|
}
|
|
77601
|
-
|
|
77602
|
-
|
|
77603
|
-
return tsColored + levelColor(entry.message);
|
|
78240
|
+
if (filterMatches && filterMatches.length > 0) {
|
|
78241
|
+
return tsColored + highlightMatches(entry.message, filterMatches);
|
|
77604
78242
|
}
|
|
77605
|
-
return tsColored + entry.message;
|
|
78243
|
+
return tsColored + colorizeTokens(entry.message);
|
|
78244
|
+
}
|
|
78245
|
+
function highlightMatches(text, matches, baseFn) {
|
|
78246
|
+
if (matches.length === 0) return baseFn ? baseFn(text) : colorizeTokens(text);
|
|
78247
|
+
const sorted = [...matches].sort((a, b) => a.start - b.start);
|
|
78248
|
+
const parts = [];
|
|
78249
|
+
let pos = 0;
|
|
78250
|
+
for (const m of sorted) {
|
|
78251
|
+
if (m.start > pos) {
|
|
78252
|
+
const segment = text.slice(pos, m.start);
|
|
78253
|
+
parts.push(baseFn ? baseFn(segment) : segment);
|
|
78254
|
+
}
|
|
78255
|
+
parts.push(`\x1B[44;37m${text.slice(m.start, m.start + m.length)}\x1B[49;39m`);
|
|
78256
|
+
pos = m.start + m.length;
|
|
78257
|
+
}
|
|
78258
|
+
if (pos < text.length) {
|
|
78259
|
+
const segment = text.slice(pos);
|
|
78260
|
+
parts.push(baseFn ? baseFn(segment) : segment);
|
|
78261
|
+
}
|
|
78262
|
+
return parts.join("");
|
|
77606
78263
|
}
|
|
77607
78264
|
function colorizeEnvLine(line) {
|
|
77608
78265
|
const eqIdx = line.indexOf("=");
|
|
@@ -77657,10 +78314,12 @@ var ContainersPanel = class {
|
|
|
77657
78314
|
shortcutKey = 1;
|
|
77658
78315
|
client;
|
|
77659
78316
|
onAction;
|
|
78317
|
+
onError;
|
|
77660
78318
|
onExec;
|
|
77661
|
-
constructor(client, onAction) {
|
|
78319
|
+
constructor(client, onAction, onError) {
|
|
77662
78320
|
this.client = client;
|
|
77663
78321
|
this.onAction = onAction;
|
|
78322
|
+
this.onError = onError ?? defaultOnError;
|
|
77664
78323
|
}
|
|
77665
78324
|
setOnExec(handler) {
|
|
77666
78325
|
this.onExec = handler;
|
|
@@ -77671,7 +78330,38 @@ var ContainersPanel = class {
|
|
|
77671
78330
|
render: (item, metrics) => {
|
|
77672
78331
|
const logs = metrics.selectedContainerLogs;
|
|
77673
78332
|
if (logs.length === 0) return "No logs available. Select a container to view logs.";
|
|
77674
|
-
|
|
78333
|
+
const lines = [];
|
|
78334
|
+
if (metrics.logSeverityCounts && metrics.logSeverityCounts.total > 0) {
|
|
78335
|
+
const c = metrics.logSeverityCounts;
|
|
78336
|
+
const parts = [];
|
|
78337
|
+
if (c.error > 0) parts.push(`\x1B[31mE:${c.error}\x1B[39m`);
|
|
78338
|
+
if (c.warn > 0) parts.push(`\x1B[33mW:${c.warn}\x1B[39m`);
|
|
78339
|
+
if (c.info > 0) parts.push(`\x1B[38;2;43;76;126mI:${c.info}\x1B[39m`);
|
|
78340
|
+
if (c.debug > 0) parts.push(`\x1B[90mD:${c.debug}\x1B[39m`);
|
|
78341
|
+
if (parts.length > 0) lines.push(parts.join(" "));
|
|
78342
|
+
}
|
|
78343
|
+
const query = metrics.logFilterString;
|
|
78344
|
+
const mode = metrics.logFilterMode;
|
|
78345
|
+
if (query) {
|
|
78346
|
+
let matchCount = 0;
|
|
78347
|
+
for (const l of logs) {
|
|
78348
|
+
const result = (0, import_sidekick_docker_shared4.filterLine)(l.message, query, mode);
|
|
78349
|
+
if (result.matched) {
|
|
78350
|
+
matchCount++;
|
|
78351
|
+
lines.push(colorizeLogEntry(l, result.matches));
|
|
78352
|
+
}
|
|
78353
|
+
}
|
|
78354
|
+
if (lines.length <= 1) {
|
|
78355
|
+
lines.push(`\x1B[90mNo logs matching "${query}"\x1B[39m`);
|
|
78356
|
+
} else {
|
|
78357
|
+
lines.splice(1, 0, `\x1B[90m${matchCount} matches (f to filter, Tab to toggle mode)\x1B[39m`);
|
|
78358
|
+
}
|
|
78359
|
+
} else {
|
|
78360
|
+
for (const l of logs) {
|
|
78361
|
+
lines.push(colorizeLogEntry(l));
|
|
78362
|
+
}
|
|
78363
|
+
}
|
|
78364
|
+
return lines.join("\n");
|
|
77675
78365
|
},
|
|
77676
78366
|
autoScrollBottom: true
|
|
77677
78367
|
},
|
|
@@ -77694,14 +78384,19 @@ var ContainersPanel = class {
|
|
|
77694
78384
|
if (cpuSeries.length > 1) {
|
|
77695
78385
|
lines.push(` ${coloredSparkline(cpuSeries, "cpu")}`);
|
|
77696
78386
|
}
|
|
77697
|
-
lines.push(colorizeDetailKey(`Memory: ${(0,
|
|
78387
|
+
lines.push(colorizeDetailKey(`Memory: ${(0, import_sidekick_docker_shared3.formatMemory)(latest.memoryUsage, latest.memoryLimit)} (${colorizePercent(latest.memoryPercent)})`));
|
|
77698
78388
|
if (memSeries.length > 1) {
|
|
77699
78389
|
lines.push(` ${coloredSparkline(memSeries, "memory")}`);
|
|
77700
78390
|
}
|
|
77701
78391
|
lines.push(
|
|
77702
|
-
colorizeDetailKey(`Net: \u25BC ${(0,
|
|
78392
|
+
colorizeDetailKey(`Net: \u25BC ${(0, import_sidekick_docker_shared3.formatBytes)(latest.networkRx)} \u25B2 ${(0, import_sidekick_docker_shared3.formatBytes)(latest.networkTx)}`),
|
|
77703
78393
|
colorizeDetailKey(`PIDs: ${latest.pids}`)
|
|
77704
78394
|
);
|
|
78395
|
+
if (metrics.logSeverityTimeSeries.length > 1) {
|
|
78396
|
+
lines.push("");
|
|
78397
|
+
lines.push(sectionHeader("Log Activity"));
|
|
78398
|
+
lines.push(` ${severitySparkline(metrics.logSeverityTimeSeries)}`);
|
|
78399
|
+
}
|
|
77705
78400
|
return lines.join("\n");
|
|
77706
78401
|
}
|
|
77707
78402
|
},
|
|
@@ -77731,7 +78426,7 @@ var ContainersPanel = class {
|
|
|
77731
78426
|
colorizeDetailKey(` Created: ${c.created.toLocaleString()}`),
|
|
77732
78427
|
"",
|
|
77733
78428
|
sectionHeader("Network"),
|
|
77734
|
-
colorizeDetailKey(` Ports: ${(0,
|
|
78429
|
+
colorizeDetailKey(` Ports: ${(0, import_sidekick_docker_shared3.formatPorts)(c.ports)}`)
|
|
77735
78430
|
];
|
|
77736
78431
|
if (c.composeProject) {
|
|
77737
78432
|
lines.push("", sectionHeader("Compose"));
|
|
@@ -77740,19 +78435,34 @@ var ContainersPanel = class {
|
|
|
77740
78435
|
}
|
|
77741
78436
|
return lines.join("\n");
|
|
77742
78437
|
}
|
|
78438
|
+
},
|
|
78439
|
+
{
|
|
78440
|
+
label: "Patterns",
|
|
78441
|
+
render: (_item, metrics) => {
|
|
78442
|
+
const templates = metrics.logTemplates;
|
|
78443
|
+
if (templates.length === 0) return "No log patterns detected yet. Patterns will appear as logs stream in.";
|
|
78444
|
+
const lines = [sectionHeader("Top Log Patterns"), ""];
|
|
78445
|
+
for (let i = 0; i < templates.length; i++) {
|
|
78446
|
+
const t = templates[i];
|
|
78447
|
+
const count = `\x1B[33m${String(t.count).padStart(5)}\x1B[39m`;
|
|
78448
|
+
const pattern = t.pattern.replace(/<\*>/g, "\x1B[90m<*>\x1B[39m");
|
|
78449
|
+
lines.push(`${count} ${pattern}`);
|
|
78450
|
+
}
|
|
78451
|
+
return lines.join("\n");
|
|
78452
|
+
}
|
|
77743
78453
|
}
|
|
77744
78454
|
];
|
|
77745
78455
|
getItems(metrics) {
|
|
77746
78456
|
return metrics.containers.map((c) => {
|
|
77747
78457
|
const uptime = compactUptime(c.status);
|
|
77748
78458
|
const portHint = c.state === "running" && c.ports.length > 0 ? `:${c.ports[0].hostPort || c.ports[0].containerPort}` : "";
|
|
77749
|
-
const namePart = portHint ? `${(0,
|
|
78459
|
+
const namePart = portHint ? `${(0, import_sidekick_docker_shared3.truncate)(c.name, 16)} ${portHint}` : (0, import_sidekick_docker_shared3.truncate)(c.name, 20);
|
|
77750
78460
|
return {
|
|
77751
78461
|
id: c.id,
|
|
77752
|
-
label: `${(0,
|
|
78462
|
+
label: `${(0, import_sidekick_docker_shared3.stateIcon)(c.state)} ${namePart}`,
|
|
77753
78463
|
sortKey: c.state === "running" ? 0 : 1,
|
|
77754
78464
|
data: c,
|
|
77755
|
-
iconColor: (0,
|
|
78465
|
+
iconColor: (0, import_sidekick_docker_shared3.stateColor)(c.state),
|
|
77756
78466
|
rightLabel: uptime,
|
|
77757
78467
|
rightColor: c.state === "running" ? "green" : "gray"
|
|
77758
78468
|
};
|
|
@@ -77765,8 +78475,7 @@ var ContainersPanel = class {
|
|
|
77765
78475
|
label: "Start",
|
|
77766
78476
|
handler: (item) => {
|
|
77767
78477
|
const c = item.data;
|
|
77768
|
-
this.client.startContainer(c.id).then(() => this.onAction()).catch(() =>
|
|
77769
|
-
});
|
|
78478
|
+
this.client.startContainer(c.id).then(() => this.onAction()).catch((e) => this.onError(String(e)));
|
|
77770
78479
|
},
|
|
77771
78480
|
condition: (item) => item.data.state !== "running"
|
|
77772
78481
|
},
|
|
@@ -77775,8 +78484,7 @@ var ContainersPanel = class {
|
|
|
77775
78484
|
label: "Stop",
|
|
77776
78485
|
handler: (item) => {
|
|
77777
78486
|
const c = item.data;
|
|
77778
|
-
this.client.stopContainer(c.id).then(() => this.onAction()).catch(() =>
|
|
77779
|
-
});
|
|
78487
|
+
this.client.stopContainer(c.id).then(() => this.onAction()).catch((e) => this.onError(String(e)));
|
|
77780
78488
|
},
|
|
77781
78489
|
condition: (item) => item.data.state === "running"
|
|
77782
78490
|
},
|
|
@@ -77785,8 +78493,7 @@ var ContainersPanel = class {
|
|
|
77785
78493
|
label: "Restart",
|
|
77786
78494
|
handler: (item) => {
|
|
77787
78495
|
const c = item.data;
|
|
77788
|
-
this.client.restartContainer(c.id).then(() => this.onAction()).catch(() =>
|
|
77789
|
-
});
|
|
78496
|
+
this.client.restartContainer(c.id).then(() => this.onAction()).catch((e) => this.onError(String(e)));
|
|
77790
78497
|
},
|
|
77791
78498
|
condition: (item) => item.data.state === "running"
|
|
77792
78499
|
},
|
|
@@ -77797,8 +78504,7 @@ var ContainersPanel = class {
|
|
|
77797
78504
|
confirmMessage: "Remove this container?",
|
|
77798
78505
|
handler: (item) => {
|
|
77799
78506
|
const c = item.data;
|
|
77800
|
-
this.client.removeContainer(c.id, true).then(() => this.onAction()).catch(() =>
|
|
77801
|
-
});
|
|
78507
|
+
this.client.removeContainer(c.id, true).then(() => this.onAction()).catch((e) => this.onError(String(e)));
|
|
77802
78508
|
}
|
|
77803
78509
|
},
|
|
77804
78510
|
{
|
|
@@ -77819,16 +78525,21 @@ var ContainersPanel = class {
|
|
|
77819
78525
|
};
|
|
77820
78526
|
|
|
77821
78527
|
// src/dashboard/panels/ServicesPanel.ts
|
|
78528
|
+
function getProjectName(d) {
|
|
78529
|
+
return d.type === "project" ? d.project.name : d.service.projectName;
|
|
78530
|
+
}
|
|
77822
78531
|
var ServicesPanel = class {
|
|
77823
78532
|
id = "services";
|
|
77824
78533
|
title = "Services";
|
|
77825
78534
|
shortcutKey = 2;
|
|
77826
78535
|
composeClient;
|
|
77827
78536
|
onAction;
|
|
78537
|
+
onError;
|
|
77828
78538
|
cwd;
|
|
77829
|
-
constructor(composeClient, onAction, cwd2) {
|
|
78539
|
+
constructor(composeClient, onAction, cwd2, onError) {
|
|
77830
78540
|
this.composeClient = composeClient;
|
|
77831
78541
|
this.onAction = onAction;
|
|
78542
|
+
this.onError = onError ?? defaultOnError;
|
|
77832
78543
|
this.cwd = cwd2;
|
|
77833
78544
|
}
|
|
77834
78545
|
detailTabs = [
|
|
@@ -77844,7 +78555,7 @@ var ServicesPanel = class {
|
|
|
77844
78555
|
colorizeDetailKey(`Status: ${colorizeState(p.status)}`),
|
|
77845
78556
|
colorizeDetailKey(`Services: ${p.services.length}`),
|
|
77846
78557
|
"",
|
|
77847
|
-
...p.services.map((s2) => ` ${(0,
|
|
78558
|
+
...p.services.map((s2) => ` ${(0, import_sidekick_docker_shared3.stateIcon)(s2.state)} ${s2.name} (${s2.image})`)
|
|
77848
78559
|
];
|
|
77849
78560
|
return lines.join("\n");
|
|
77850
78561
|
}
|
|
@@ -77886,13 +78597,13 @@ var ServicesPanel = class {
|
|
|
77886
78597
|
rightColor: projectIconColor
|
|
77887
78598
|
});
|
|
77888
78599
|
for (const service of project.services) {
|
|
77889
|
-
const icon = (0,
|
|
78600
|
+
const icon = (0, import_sidekick_docker_shared3.stateIcon)(service.state);
|
|
77890
78601
|
items.push({
|
|
77891
78602
|
id: `service:${project.name}:${service.name}`,
|
|
77892
|
-
label: ` ${icon} ${(0,
|
|
78603
|
+
label: ` ${icon} ${(0, import_sidekick_docker_shared3.truncate)(service.name, 18)}`,
|
|
77893
78604
|
sortKey: sortKey++,
|
|
77894
78605
|
data: { type: "service", service },
|
|
77895
|
-
iconColor: (0,
|
|
78606
|
+
iconColor: (0, import_sidekick_docker_shared3.stateColor)(service.state)
|
|
77896
78607
|
});
|
|
77897
78608
|
}
|
|
77898
78609
|
}
|
|
@@ -77913,9 +78624,7 @@ var ServicesPanel = class {
|
|
|
77913
78624
|
label: "Up",
|
|
77914
78625
|
handler: (item) => {
|
|
77915
78626
|
const d = item.data;
|
|
77916
|
-
|
|
77917
|
-
this.composeClient.up(projectName, this.cwd).then(() => this.onAction()).catch(() => {
|
|
77918
|
-
});
|
|
78627
|
+
this.composeClient.up(getProjectName(d), this.cwd).then(() => this.onAction()).catch((e) => this.onError(String(e)));
|
|
77919
78628
|
},
|
|
77920
78629
|
condition: (item) => item.data !== null
|
|
77921
78630
|
},
|
|
@@ -77926,9 +78635,7 @@ var ServicesPanel = class {
|
|
|
77926
78635
|
confirmMessage: "Bring down this compose project?",
|
|
77927
78636
|
handler: (item) => {
|
|
77928
78637
|
const d = item.data;
|
|
77929
|
-
|
|
77930
|
-
this.composeClient.down(projectName, this.cwd).then(() => this.onAction()).catch(() => {
|
|
77931
|
-
});
|
|
78638
|
+
this.composeClient.down(getProjectName(d), this.cwd).then(() => this.onAction()).catch((e) => this.onError(String(e)));
|
|
77932
78639
|
},
|
|
77933
78640
|
condition: (item) => item.data !== null
|
|
77934
78641
|
},
|
|
@@ -77938,11 +78645,9 @@ var ServicesPanel = class {
|
|
|
77938
78645
|
handler: (item) => {
|
|
77939
78646
|
const d = item.data;
|
|
77940
78647
|
if (d.type === "service") {
|
|
77941
|
-
this.composeClient.restart(d.service.projectName, d.service.name, this.cwd).then(() => this.onAction()).catch(() =>
|
|
77942
|
-
});
|
|
78648
|
+
this.composeClient.restart(d.service.projectName, d.service.name, this.cwd).then(() => this.onAction()).catch((e) => this.onError(String(e)));
|
|
77943
78649
|
} else {
|
|
77944
|
-
this.composeClient.restart(d.project.name, void 0, this.cwd).then(() => this.onAction()).catch(() =>
|
|
77945
|
-
});
|
|
78650
|
+
this.composeClient.restart(d.project.name, void 0, this.cwd).then(() => this.onAction()).catch((e) => this.onError(String(e)));
|
|
77946
78651
|
}
|
|
77947
78652
|
},
|
|
77948
78653
|
condition: (item) => item.data !== null
|
|
@@ -77953,11 +78658,9 @@ var ServicesPanel = class {
|
|
|
77953
78658
|
handler: (item) => {
|
|
77954
78659
|
const d = item.data;
|
|
77955
78660
|
if (d.type === "service") {
|
|
77956
|
-
this.composeClient.stop(d.service.projectName, d.service.name, this.cwd).then(() => this.onAction()).catch(() =>
|
|
77957
|
-
});
|
|
78661
|
+
this.composeClient.stop(d.service.projectName, d.service.name, this.cwd).then(() => this.onAction()).catch((e) => this.onError(String(e)));
|
|
77958
78662
|
} else {
|
|
77959
|
-
this.composeClient.stop(d.project.name, void 0, this.cwd).then(() => this.onAction()).catch(() =>
|
|
77960
|
-
});
|
|
78663
|
+
this.composeClient.stop(d.project.name, void 0, this.cwd).then(() => this.onAction()).catch((e) => this.onError(String(e)));
|
|
77961
78664
|
}
|
|
77962
78665
|
},
|
|
77963
78666
|
condition: (item) => item.data !== null
|
|
@@ -77979,9 +78682,11 @@ var ImagesPanel = class {
|
|
|
77979
78682
|
shortcutKey = 3;
|
|
77980
78683
|
client;
|
|
77981
78684
|
onAction;
|
|
77982
|
-
|
|
78685
|
+
onError;
|
|
78686
|
+
constructor(client, onAction, onError) {
|
|
77983
78687
|
this.client = client;
|
|
77984
78688
|
this.onAction = onAction;
|
|
78689
|
+
this.onError = onError ?? defaultOnError;
|
|
77985
78690
|
}
|
|
77986
78691
|
detailTabs = [
|
|
77987
78692
|
{
|
|
@@ -77991,7 +78696,7 @@ var ImagesPanel = class {
|
|
|
77991
78696
|
return [
|
|
77992
78697
|
colorizeDetailKey(`ID: ${colorizeId(img.id)}`),
|
|
77993
78698
|
colorizeDetailKey(`Tags: ${img.repoTags.join(", ")}`),
|
|
77994
|
-
colorizeDetailKey(`Size: ${(0,
|
|
78699
|
+
colorizeDetailKey(`Size: ${(0, import_sidekick_docker_shared3.formatBytes)(img.size)}`),
|
|
77995
78700
|
colorizeDetailKey(`Created: ${img.created.toLocaleString()}`),
|
|
77996
78701
|
colorizeDetailKey(`Dangling: ${colorizeBool(img.isDangling)}`)
|
|
77997
78702
|
].join("\n");
|
|
@@ -78004,11 +78709,11 @@ var ImagesPanel = class {
|
|
|
78004
78709
|
const icon = img.isDangling ? "\u25CB" : "\u25CF";
|
|
78005
78710
|
return {
|
|
78006
78711
|
id: img.id,
|
|
78007
|
-
label: `${icon} ${(0,
|
|
78712
|
+
label: `${icon} ${(0, import_sidekick_docker_shared3.truncate)(tag, 20)}`,
|
|
78008
78713
|
sortKey: img.isDangling ? 1 : 0,
|
|
78009
78714
|
data: img,
|
|
78010
78715
|
iconColor: img.isDangling ? "gray" : "#2B4C7E",
|
|
78011
|
-
rightLabel: (0,
|
|
78716
|
+
rightLabel: (0, import_sidekick_docker_shared3.formatBytes)(img.size),
|
|
78012
78717
|
rightColor: "gray"
|
|
78013
78718
|
};
|
|
78014
78719
|
});
|
|
@@ -78022,8 +78727,7 @@ var ImagesPanel = class {
|
|
|
78022
78727
|
confirmMessage: "Remove this image?",
|
|
78023
78728
|
handler: (item) => {
|
|
78024
78729
|
const img = item.data;
|
|
78025
|
-
this.client.removeImage(img.id).then(() => this.onAction()).catch(() =>
|
|
78026
|
-
});
|
|
78730
|
+
this.client.removeImage(img.id).then(() => this.onAction()).catch((e) => this.onError(String(e)));
|
|
78027
78731
|
}
|
|
78028
78732
|
},
|
|
78029
78733
|
{
|
|
@@ -78032,8 +78736,7 @@ var ImagesPanel = class {
|
|
|
78032
78736
|
confirm: true,
|
|
78033
78737
|
confirmMessage: "Prune all dangling images?",
|
|
78034
78738
|
handler: () => {
|
|
78035
|
-
this.client.pruneImages().then(() => this.onAction()).catch(() =>
|
|
78036
|
-
});
|
|
78739
|
+
this.client.pruneImages().then(() => this.onAction()).catch((e) => this.onError(String(e)));
|
|
78037
78740
|
}
|
|
78038
78741
|
}
|
|
78039
78742
|
];
|
|
@@ -78051,9 +78754,11 @@ var VolumesPanel = class {
|
|
|
78051
78754
|
shortcutKey = 4;
|
|
78052
78755
|
client;
|
|
78053
78756
|
onAction;
|
|
78054
|
-
|
|
78757
|
+
onError;
|
|
78758
|
+
constructor(client, onAction, onError) {
|
|
78055
78759
|
this.client = client;
|
|
78056
78760
|
this.onAction = onAction;
|
|
78761
|
+
this.onError = onError ?? defaultOnError;
|
|
78057
78762
|
}
|
|
78058
78763
|
detailTabs = [
|
|
78059
78764
|
{
|
|
@@ -78075,7 +78780,7 @@ var VolumesPanel = class {
|
|
|
78075
78780
|
const icon = vol.isInUse ? "\u25CF" : "\u25CB";
|
|
78076
78781
|
return {
|
|
78077
78782
|
id: vol.name,
|
|
78078
|
-
label: `${icon} ${(0,
|
|
78783
|
+
label: `${icon} ${(0, import_sidekick_docker_shared3.truncate)(vol.name, 20)}`,
|
|
78079
78784
|
sortKey: vol.isInUse ? 0 : 1,
|
|
78080
78785
|
data: vol,
|
|
78081
78786
|
iconColor: vol.isInUse ? "green" : "gray",
|
|
@@ -78093,8 +78798,7 @@ var VolumesPanel = class {
|
|
|
78093
78798
|
confirmMessage: "Remove this volume?",
|
|
78094
78799
|
handler: (item) => {
|
|
78095
78800
|
const vol = item.data;
|
|
78096
|
-
this.client.removeVolume(vol.name).then(() => this.onAction()).catch(() =>
|
|
78097
|
-
});
|
|
78801
|
+
this.client.removeVolume(vol.name).then(() => this.onAction()).catch((e) => this.onError(String(e)));
|
|
78098
78802
|
},
|
|
78099
78803
|
condition: (item) => !item.data.isInUse
|
|
78100
78804
|
},
|
|
@@ -78104,8 +78808,7 @@ var VolumesPanel = class {
|
|
|
78104
78808
|
confirm: true,
|
|
78105
78809
|
confirmMessage: "Prune all unused volumes?",
|
|
78106
78810
|
handler: () => {
|
|
78107
|
-
this.client.pruneVolumes().then(() => this.onAction()).catch(() =>
|
|
78108
|
-
});
|
|
78811
|
+
this.client.pruneVolumes().then(() => this.onAction()).catch((e) => this.onError(String(e)));
|
|
78109
78812
|
}
|
|
78110
78813
|
}
|
|
78111
78814
|
];
|
|
@@ -78123,9 +78826,11 @@ var NetworksPanel = class {
|
|
|
78123
78826
|
shortcutKey = 5;
|
|
78124
78827
|
client;
|
|
78125
78828
|
onAction;
|
|
78126
|
-
|
|
78829
|
+
onError;
|
|
78830
|
+
constructor(client, onAction, onError) {
|
|
78127
78831
|
this.client = client;
|
|
78128
78832
|
this.onAction = onAction;
|
|
78833
|
+
this.onError = onError ?? defaultOnError;
|
|
78129
78834
|
}
|
|
78130
78835
|
detailTabs = [
|
|
78131
78836
|
{
|
|
@@ -78157,7 +78862,7 @@ var NetworksPanel = class {
|
|
|
78157
78862
|
const countLabel = net.containers.length > 0 ? `${net.containers.length}` : "";
|
|
78158
78863
|
return {
|
|
78159
78864
|
id: net.id,
|
|
78160
|
-
label: `${icon} ${(0,
|
|
78865
|
+
label: `${icon} ${(0, import_sidekick_docker_shared3.truncate)(net.name, 20)}`,
|
|
78161
78866
|
sortKey: net.isDefault ? 0 : 1,
|
|
78162
78867
|
data: net,
|
|
78163
78868
|
iconColor: net.isDefault ? "#2B4C7E" : "gray",
|
|
@@ -78175,8 +78880,7 @@ var NetworksPanel = class {
|
|
|
78175
78880
|
confirmMessage: "Remove this network?",
|
|
78176
78881
|
handler: (item) => {
|
|
78177
78882
|
const net = item.data;
|
|
78178
|
-
this.client.removeNetwork(net.id).then(() => this.onAction()).catch(() =>
|
|
78179
|
-
});
|
|
78883
|
+
this.client.removeNetwork(net.id).then(() => this.onAction()).catch((e) => this.onError(String(e)));
|
|
78180
78884
|
},
|
|
78181
78885
|
condition: (item) => {
|
|
78182
78886
|
const net = item.data;
|
|
@@ -78189,8 +78893,7 @@ var NetworksPanel = class {
|
|
|
78189
78893
|
confirm: true,
|
|
78190
78894
|
confirmMessage: "Prune all unused networks?",
|
|
78191
78895
|
handler: () => {
|
|
78192
|
-
this.client.pruneNetworks().then(() => this.onAction()).catch(() =>
|
|
78193
|
-
});
|
|
78896
|
+
this.client.pruneNetworks().then(() => this.onAction()).catch((e) => this.onError(String(e)));
|
|
78194
78897
|
}
|
|
78195
78898
|
}
|
|
78196
78899
|
];
|
|
@@ -78202,14 +78905,18 @@ var NetworksPanel = class {
|
|
|
78202
78905
|
};
|
|
78203
78906
|
|
|
78204
78907
|
// src/dashboard/LogStreamManager.ts
|
|
78205
|
-
var
|
|
78908
|
+
var import_sidekick_docker_shared5 = __toESM(require_dist(), 1);
|
|
78206
78909
|
var LogStreamManager = class {
|
|
78207
78910
|
client;
|
|
78208
78911
|
currentContainerId = null;
|
|
78209
78912
|
logs = [];
|
|
78210
78913
|
aborted = false;
|
|
78211
78914
|
streamPromise = null;
|
|
78915
|
+
reconnect = new import_sidekick_docker_shared5.ReconnectScheduler();
|
|
78212
78916
|
onChange;
|
|
78917
|
+
analytics = new import_sidekick_docker_shared5.LogAnalytics();
|
|
78918
|
+
timeSeries = new import_sidekick_docker_shared5.LogSeverityTimeSeries();
|
|
78919
|
+
templateEngine = new import_sidekick_docker_shared5.LogTemplateEngine();
|
|
78213
78920
|
constructor(client, onChange) {
|
|
78214
78921
|
this.client = client;
|
|
78215
78922
|
this.onChange = onChange;
|
|
@@ -78220,8 +78927,12 @@ var LogStreamManager = class {
|
|
|
78220
78927
|
this.stop();
|
|
78221
78928
|
this.currentContainerId = containerId;
|
|
78222
78929
|
this.logs = [];
|
|
78930
|
+
this.analytics.reset();
|
|
78931
|
+
this.timeSeries.reset();
|
|
78932
|
+
this.templateEngine.reset();
|
|
78223
78933
|
if (!containerId) return;
|
|
78224
78934
|
this.aborted = false;
|
|
78935
|
+
this.reconnect.reset();
|
|
78225
78936
|
this.streamPromise = this.streamLogs(containerId);
|
|
78226
78937
|
}
|
|
78227
78938
|
async streamLogs(containerId) {
|
|
@@ -78232,22 +78943,47 @@ var LogStreamManager = class {
|
|
|
78232
78943
|
})) {
|
|
78233
78944
|
if (this.aborted || this.currentContainerId !== containerId) break;
|
|
78234
78945
|
this.logs.push(entry);
|
|
78235
|
-
|
|
78946
|
+
const severity = this.analytics.push(entry.message);
|
|
78947
|
+
this.timeSeries.push(severity);
|
|
78948
|
+
this.templateEngine.push(entry.message);
|
|
78949
|
+
if (this.logs.length > import_sidekick_docker_shared5.MAX_LOG_LINES) {
|
|
78236
78950
|
this.logs.shift();
|
|
78237
78951
|
}
|
|
78238
78952
|
this.onChange();
|
|
78239
78953
|
}
|
|
78240
|
-
|
|
78954
|
+
this.reconnect.reset();
|
|
78955
|
+
} catch (err) {
|
|
78956
|
+
console.debug("log stream error:", (0, import_sidekick_docker_shared5.errorMessage)(err));
|
|
78957
|
+
}
|
|
78958
|
+
if (!this.aborted && this.currentContainerId === containerId) {
|
|
78959
|
+
const scheduled = this.reconnect.schedule(() => {
|
|
78960
|
+
if (!this.aborted && this.currentContainerId === containerId) {
|
|
78961
|
+
this.streamPromise = this.streamLogs(containerId);
|
|
78962
|
+
}
|
|
78963
|
+
});
|
|
78964
|
+
if (!scheduled) {
|
|
78965
|
+
console.debug(`log stream: gave up reconnecting for ${containerId}`);
|
|
78966
|
+
}
|
|
78241
78967
|
}
|
|
78242
78968
|
}
|
|
78243
78969
|
stop() {
|
|
78244
78970
|
this.aborted = true;
|
|
78245
78971
|
this.currentContainerId = null;
|
|
78246
78972
|
this.streamPromise = null;
|
|
78973
|
+
this.reconnect.clear();
|
|
78247
78974
|
}
|
|
78248
78975
|
getLogs() {
|
|
78249
78976
|
return this.logs;
|
|
78250
78977
|
}
|
|
78978
|
+
getSeverityCounts() {
|
|
78979
|
+
return this.analytics.getCounts();
|
|
78980
|
+
}
|
|
78981
|
+
getSeverityTimeSeries() {
|
|
78982
|
+
return this.timeSeries.getDominantSeries();
|
|
78983
|
+
}
|
|
78984
|
+
getTemplates(limit = 20) {
|
|
78985
|
+
return this.templateEngine.getTemplates(limit);
|
|
78986
|
+
}
|
|
78251
78987
|
getCurrentContainerId() {
|
|
78252
78988
|
return this.currentContainerId;
|
|
78253
78989
|
}
|
|
@@ -78257,12 +78993,14 @@ var LogStreamManager = class {
|
|
|
78257
78993
|
};
|
|
78258
78994
|
|
|
78259
78995
|
// src/dashboard/StatsStreamManager.ts
|
|
78996
|
+
var import_sidekick_docker_shared6 = __toESM(require_dist(), 1);
|
|
78260
78997
|
var StatsStreamManager = class {
|
|
78261
78998
|
client;
|
|
78262
78999
|
collector;
|
|
78263
79000
|
currentContainerId = null;
|
|
78264
79001
|
aborted = false;
|
|
78265
79002
|
streamPromise = null;
|
|
79003
|
+
reconnect = new import_sidekick_docker_shared6.ReconnectScheduler();
|
|
78266
79004
|
onChange;
|
|
78267
79005
|
loadingInterval = null;
|
|
78268
79006
|
constructor(client, collector, onChange) {
|
|
@@ -78277,6 +79015,7 @@ var StatsStreamManager = class {
|
|
|
78277
79015
|
this.currentContainerId = containerId;
|
|
78278
79016
|
if (!containerId) return;
|
|
78279
79017
|
this.aborted = false;
|
|
79018
|
+
this.reconnect.reset();
|
|
78280
79019
|
this.loadingInterval = setInterval(() => this.onChange(), 200);
|
|
78281
79020
|
this.streamPromise = this.streamStats(containerId);
|
|
78282
79021
|
}
|
|
@@ -78294,12 +79033,26 @@ var StatsStreamManager = class {
|
|
|
78294
79033
|
this.clearLoadingInterval();
|
|
78295
79034
|
this.onChange();
|
|
78296
79035
|
}
|
|
78297
|
-
|
|
79036
|
+
this.reconnect.reset();
|
|
79037
|
+
} catch (err) {
|
|
79038
|
+
console.debug("stats stream error:", (0, import_sidekick_docker_shared6.errorMessage)(err));
|
|
79039
|
+
}
|
|
79040
|
+
if (!this.aborted && this.currentContainerId === containerId) {
|
|
79041
|
+
const scheduled = this.reconnect.schedule(() => {
|
|
79042
|
+
if (!this.aborted && this.currentContainerId === containerId) {
|
|
79043
|
+
this.loadingInterval = setInterval(() => this.onChange(), 200);
|
|
79044
|
+
this.streamPromise = this.streamStats(containerId);
|
|
79045
|
+
}
|
|
79046
|
+
});
|
|
79047
|
+
if (!scheduled) {
|
|
79048
|
+
console.debug(`stats stream: gave up reconnecting for ${containerId}`);
|
|
79049
|
+
}
|
|
78298
79050
|
}
|
|
78299
79051
|
}
|
|
78300
79052
|
stop() {
|
|
78301
79053
|
this.aborted = true;
|
|
78302
79054
|
this.clearLoadingInterval();
|
|
79055
|
+
this.reconnect.clear();
|
|
78303
79056
|
this.currentContainerId = null;
|
|
78304
79057
|
this.streamPromise = null;
|
|
78305
79058
|
}
|
|
@@ -78311,18 +79064,18 @@ var StatsStreamManager = class {
|
|
|
78311
79064
|
}
|
|
78312
79065
|
dispose() {
|
|
78313
79066
|
this.stop();
|
|
78314
|
-
this.clearLoadingInterval();
|
|
78315
79067
|
}
|
|
78316
79068
|
};
|
|
78317
79069
|
|
|
78318
79070
|
// src/dashboard/ComposeLogStreamManager.ts
|
|
78319
|
-
var
|
|
79071
|
+
var import_sidekick_docker_shared7 = __toESM(require_dist(), 1);
|
|
78320
79072
|
var ComposeLogStreamManager = class {
|
|
78321
79073
|
composeClient;
|
|
78322
79074
|
currentProject = null;
|
|
78323
79075
|
currentService = null;
|
|
78324
79076
|
logs = [];
|
|
78325
79077
|
aborted = false;
|
|
79078
|
+
reconnect = new import_sidekick_docker_shared7.ReconnectScheduler();
|
|
78326
79079
|
onChange;
|
|
78327
79080
|
constructor(composeClient, onChange) {
|
|
78328
79081
|
this.composeClient = composeClient;
|
|
@@ -78336,6 +79089,7 @@ var ComposeLogStreamManager = class {
|
|
|
78336
79089
|
this.logs = [];
|
|
78337
79090
|
if (!project) return;
|
|
78338
79091
|
this.aborted = false;
|
|
79092
|
+
this.reconnect.reset();
|
|
78339
79093
|
this.streamLogs(project, service);
|
|
78340
79094
|
}
|
|
78341
79095
|
async streamLogs(project, service) {
|
|
@@ -78343,18 +79097,31 @@ var ComposeLogStreamManager = class {
|
|
|
78343
79097
|
for await (const entry of this.composeClient.streamLogs(project, service ?? void 0)) {
|
|
78344
79098
|
if (this.aborted || this.currentProject !== project) break;
|
|
78345
79099
|
this.logs.push(entry);
|
|
78346
|
-
if (this.logs.length >
|
|
79100
|
+
if (this.logs.length > import_sidekick_docker_shared7.MAX_LOG_LINES) {
|
|
78347
79101
|
this.logs.shift();
|
|
78348
79102
|
}
|
|
78349
79103
|
this.onChange();
|
|
78350
79104
|
}
|
|
78351
|
-
|
|
79105
|
+
this.reconnect.reset();
|
|
79106
|
+
} catch (err) {
|
|
79107
|
+
console.debug("compose log stream error:", (0, import_sidekick_docker_shared7.errorMessage)(err));
|
|
79108
|
+
}
|
|
79109
|
+
if (!this.aborted && this.currentProject === project) {
|
|
79110
|
+
const scheduled = this.reconnect.schedule(() => {
|
|
79111
|
+
if (!this.aborted && this.currentProject === project) {
|
|
79112
|
+
this.streamLogs(project, service);
|
|
79113
|
+
}
|
|
79114
|
+
});
|
|
79115
|
+
if (!scheduled) {
|
|
79116
|
+
console.debug(`compose log stream: gave up reconnecting for ${project}`);
|
|
79117
|
+
}
|
|
78352
79118
|
}
|
|
78353
79119
|
}
|
|
78354
79120
|
stop() {
|
|
78355
79121
|
this.aborted = true;
|
|
78356
79122
|
this.currentProject = null;
|
|
78357
79123
|
this.currentService = null;
|
|
79124
|
+
this.reconnect.clear();
|
|
78358
79125
|
}
|
|
78359
79126
|
getLogs() {
|
|
78360
79127
|
return this.logs;
|
|
@@ -78365,7 +79132,7 @@ var ComposeLogStreamManager = class {
|
|
|
78365
79132
|
};
|
|
78366
79133
|
|
|
78367
79134
|
// src/dashboard/ink/Dashboard.tsx
|
|
78368
|
-
var
|
|
79135
|
+
var import_react36 = __toESM(require_react(), 1);
|
|
78369
79136
|
await init_build2();
|
|
78370
79137
|
|
|
78371
79138
|
// src/dashboard/ink/useTerminalSize.ts
|
|
@@ -78438,6 +79205,324 @@ function useWindowedScroll({ totalItems, viewportHeight }) {
|
|
|
78438
79205
|
};
|
|
78439
79206
|
}
|
|
78440
79207
|
|
|
79208
|
+
// src/dashboard/ink/useKeyboardHandler.ts
|
|
79209
|
+
await init_build2();
|
|
79210
|
+
function executeAction(action, item, dispatch, addToast) {
|
|
79211
|
+
if (action.confirm) {
|
|
79212
|
+
dispatch({ type: "SET_CONFIRM", action: () => {
|
|
79213
|
+
action.handler(item);
|
|
79214
|
+
addToast(action.label, "info");
|
|
79215
|
+
}, message: action.confirmMessage || "Are you sure?" });
|
|
79216
|
+
} else {
|
|
79217
|
+
action.handler(item);
|
|
79218
|
+
addToast(action.label, "info");
|
|
79219
|
+
}
|
|
79220
|
+
}
|
|
79221
|
+
function handleFilterInput(input, key, opts) {
|
|
79222
|
+
const { currentValue, setAction, clearToast, dispatch, addToast, onTab } = opts;
|
|
79223
|
+
if (key.escape) {
|
|
79224
|
+
if (currentValue && clearToast) addToast(clearToast, "info");
|
|
79225
|
+
dispatch({ type: setAction, value: "" });
|
|
79226
|
+
dispatch({ type: "SET_OVERLAY", overlay: null });
|
|
79227
|
+
return;
|
|
79228
|
+
}
|
|
79229
|
+
if (key.return) {
|
|
79230
|
+
if (setAction === "SET_FILTER" && currentValue) addToast(`Filter: "${currentValue}"`, "info");
|
|
79231
|
+
dispatch({ type: "SET_OVERLAY", overlay: null });
|
|
79232
|
+
return;
|
|
79233
|
+
}
|
|
79234
|
+
if (key.tab && onTab) {
|
|
79235
|
+
onTab();
|
|
79236
|
+
return;
|
|
79237
|
+
}
|
|
79238
|
+
if (key.backspace || key.delete) {
|
|
79239
|
+
dispatch({ type: setAction, value: currentValue.slice(0, -1) });
|
|
79240
|
+
return;
|
|
79241
|
+
}
|
|
79242
|
+
if (input && !key.ctrl && !key.meta) {
|
|
79243
|
+
dispatch({ type: setAction, value: currentValue + input });
|
|
79244
|
+
}
|
|
79245
|
+
}
|
|
79246
|
+
function useKeyboardHandler(ctx) {
|
|
79247
|
+
const { exit } = use_app_default();
|
|
79248
|
+
const { state, dispatch, panels, panel, selectedItem, contextActions, clampedSelection, currentItems, detailLines, detailViewportHeight, detailTabs, tabIdx, panelActions, sideScroll, addToast, rotatePhrase } = ctx;
|
|
79249
|
+
use_input_default((input, key) => {
|
|
79250
|
+
if (state.overlay === "exec") return;
|
|
79251
|
+
rotatePhrase();
|
|
79252
|
+
if (input === "q" || key.ctrl && input === "c") {
|
|
79253
|
+
if (state.overlay) {
|
|
79254
|
+
dispatch({ type: "SET_OVERLAY", overlay: null });
|
|
79255
|
+
return;
|
|
79256
|
+
}
|
|
79257
|
+
exit();
|
|
79258
|
+
return;
|
|
79259
|
+
}
|
|
79260
|
+
if (state.overlay === "confirm") {
|
|
79261
|
+
if (input === "y" || input === "Y") {
|
|
79262
|
+
state.confirmAction?.();
|
|
79263
|
+
dispatch({ type: "SET_CONFIRM", action: null, message: "" });
|
|
79264
|
+
return;
|
|
79265
|
+
}
|
|
79266
|
+
if (input === "n" || input === "N" || key.escape) {
|
|
79267
|
+
dispatch({ type: "SET_CONFIRM", action: null, message: "" });
|
|
79268
|
+
return;
|
|
79269
|
+
}
|
|
79270
|
+
return;
|
|
79271
|
+
}
|
|
79272
|
+
if (state.overlay === "filter") {
|
|
79273
|
+
handleFilterInput(input, key, {
|
|
79274
|
+
currentValue: state.filterString,
|
|
79275
|
+
setAction: "SET_FILTER",
|
|
79276
|
+
clearToast: "Filter cleared",
|
|
79277
|
+
dispatch,
|
|
79278
|
+
addToast
|
|
79279
|
+
});
|
|
79280
|
+
return;
|
|
79281
|
+
}
|
|
79282
|
+
if (state.overlay === "log-filter") {
|
|
79283
|
+
handleFilterInput(input, key, {
|
|
79284
|
+
currentValue: state.logFilterString,
|
|
79285
|
+
setAction: "SET_LOG_FILTER",
|
|
79286
|
+
clearToast: "Log filter cleared",
|
|
79287
|
+
dispatch,
|
|
79288
|
+
addToast,
|
|
79289
|
+
onTab: () => dispatch({ type: "TOGGLE_LOG_FILTER_MODE" })
|
|
79290
|
+
});
|
|
79291
|
+
return;
|
|
79292
|
+
}
|
|
79293
|
+
if (state.overlay === "context-menu") {
|
|
79294
|
+
if (key.escape) {
|
|
79295
|
+
dispatch({ type: "SET_OVERLAY", overlay: null });
|
|
79296
|
+
return;
|
|
79297
|
+
}
|
|
79298
|
+
if (input === "j" || key.downArrow) {
|
|
79299
|
+
dispatch({ type: "CONTEXT_MENU_NAV", delta: 1, itemCount: contextActions.length });
|
|
79300
|
+
return;
|
|
79301
|
+
}
|
|
79302
|
+
if (input === "k" || key.upArrow) {
|
|
79303
|
+
dispatch({ type: "CONTEXT_MENU_NAV", delta: -1, itemCount: contextActions.length });
|
|
79304
|
+
return;
|
|
79305
|
+
}
|
|
79306
|
+
if (key.return) {
|
|
79307
|
+
const action = contextActions[state.contextMenuIndex];
|
|
79308
|
+
if (action && selectedItem) {
|
|
79309
|
+
executeAction(action, selectedItem, dispatch, addToast);
|
|
79310
|
+
dispatch({ type: "SET_OVERLAY", overlay: null });
|
|
79311
|
+
}
|
|
79312
|
+
return;
|
|
79313
|
+
}
|
|
79314
|
+
const match = contextActions.find((a) => a.key === input);
|
|
79315
|
+
if (match && selectedItem) {
|
|
79316
|
+
executeAction(match, selectedItem, dispatch, addToast);
|
|
79317
|
+
dispatch({ type: "SET_OVERLAY", overlay: null });
|
|
79318
|
+
}
|
|
79319
|
+
return;
|
|
79320
|
+
}
|
|
79321
|
+
if (state.overlay === "help") {
|
|
79322
|
+
if (key.escape || input === "?") {
|
|
79323
|
+
dispatch({ type: "SET_OVERLAY", overlay: null });
|
|
79324
|
+
}
|
|
79325
|
+
return;
|
|
79326
|
+
}
|
|
79327
|
+
if (state.overlay === "version") {
|
|
79328
|
+
if (key.escape || input === "V") {
|
|
79329
|
+
dispatch({ type: "SET_OVERLAY", overlay: null });
|
|
79330
|
+
}
|
|
79331
|
+
return;
|
|
79332
|
+
}
|
|
79333
|
+
if (key.escape) {
|
|
79334
|
+
if (state.filterString) {
|
|
79335
|
+
dispatch({ type: "SET_FILTER", value: "" });
|
|
79336
|
+
return;
|
|
79337
|
+
}
|
|
79338
|
+
if (state.focusTarget === "detail") {
|
|
79339
|
+
dispatch({ type: "SET_FOCUS", target: "side" });
|
|
79340
|
+
return;
|
|
79341
|
+
}
|
|
79342
|
+
return;
|
|
79343
|
+
}
|
|
79344
|
+
if (input === "?") {
|
|
79345
|
+
dispatch({ type: "SET_OVERLAY", overlay: "help" });
|
|
79346
|
+
return;
|
|
79347
|
+
}
|
|
79348
|
+
if (input === "V") {
|
|
79349
|
+
dispatch({ type: "SET_OVERLAY", overlay: "version" });
|
|
79350
|
+
return;
|
|
79351
|
+
}
|
|
79352
|
+
const num = parseInt(input, 10);
|
|
79353
|
+
if (num >= 1 && num <= panels.length) {
|
|
79354
|
+
panels[state.activePanelIndex]?.onDeactivate?.();
|
|
79355
|
+
dispatch({ type: "SWITCH_PANEL", index: num - 1 });
|
|
79356
|
+
panels[num - 1]?.onActivate?.();
|
|
79357
|
+
return;
|
|
79358
|
+
}
|
|
79359
|
+
if (key.tab) {
|
|
79360
|
+
dispatch({ type: "TOGGLE_FOCUS" });
|
|
79361
|
+
return;
|
|
79362
|
+
}
|
|
79363
|
+
if (input === "z") {
|
|
79364
|
+
dispatch({ type: "CYCLE_LAYOUT" });
|
|
79365
|
+
addToast(`Layout: ${state.layoutMode === "normal" ? "Expanded" : "Normal"}`, "info");
|
|
79366
|
+
return;
|
|
79367
|
+
}
|
|
79368
|
+
if (input === "/") {
|
|
79369
|
+
dispatch({ type: "SET_OVERLAY", overlay: "filter" });
|
|
79370
|
+
return;
|
|
79371
|
+
}
|
|
79372
|
+
if (input === "f") {
|
|
79373
|
+
if (panel.id === "containers" && tabIdx === 0) {
|
|
79374
|
+
dispatch({ type: "SET_OVERLAY", overlay: "log-filter" });
|
|
79375
|
+
return;
|
|
79376
|
+
}
|
|
79377
|
+
}
|
|
79378
|
+
if (input === "x") {
|
|
79379
|
+
if (selectedItem && panelActions.length > 0) {
|
|
79380
|
+
dispatch({ type: "SET_OVERLAY", overlay: "context-menu" });
|
|
79381
|
+
}
|
|
79382
|
+
return;
|
|
79383
|
+
}
|
|
79384
|
+
if (input === "[") {
|
|
79385
|
+
dispatch({ type: "CYCLE_DETAIL_TAB", direction: -1, tabCount: detailTabs.length });
|
|
79386
|
+
return;
|
|
79387
|
+
}
|
|
79388
|
+
if (input === "]") {
|
|
79389
|
+
dispatch({ type: "CYCLE_DETAIL_TAB", direction: 1, tabCount: detailTabs.length });
|
|
79390
|
+
return;
|
|
79391
|
+
}
|
|
79392
|
+
if (state.focusTarget === "side") {
|
|
79393
|
+
if (input === "j" || key.downArrow) {
|
|
79394
|
+
if (clampedSelection < currentItems.length - 1) {
|
|
79395
|
+
dispatch({ type: "SELECT_ITEM", index: clampedSelection + 1 });
|
|
79396
|
+
sideScroll.selectNext();
|
|
79397
|
+
}
|
|
79398
|
+
return;
|
|
79399
|
+
}
|
|
79400
|
+
if (input === "k" || key.upArrow) {
|
|
79401
|
+
if (clampedSelection > 0) {
|
|
79402
|
+
dispatch({ type: "SELECT_ITEM", index: clampedSelection - 1 });
|
|
79403
|
+
sideScroll.selectPrev();
|
|
79404
|
+
}
|
|
79405
|
+
return;
|
|
79406
|
+
}
|
|
79407
|
+
if (input === "g") {
|
|
79408
|
+
dispatch({ type: "SELECT_ITEM", index: 0 });
|
|
79409
|
+
sideScroll.selectFirst();
|
|
79410
|
+
return;
|
|
79411
|
+
}
|
|
79412
|
+
if (input === "G") {
|
|
79413
|
+
dispatch({ type: "SELECT_ITEM", index: Math.max(0, currentItems.length - 1) });
|
|
79414
|
+
sideScroll.selectLast();
|
|
79415
|
+
return;
|
|
79416
|
+
}
|
|
79417
|
+
if (key.return) {
|
|
79418
|
+
dispatch({ type: "SET_FOCUS", target: "detail" });
|
|
79419
|
+
return;
|
|
79420
|
+
}
|
|
79421
|
+
}
|
|
79422
|
+
if (state.focusTarget === "detail") {
|
|
79423
|
+
if (input === "j" || key.downArrow) {
|
|
79424
|
+
dispatch({ type: "SCROLL_DETAIL_DELTA", delta: 1, totalLines: detailLines.length, viewportHeight: detailViewportHeight });
|
|
79425
|
+
return;
|
|
79426
|
+
}
|
|
79427
|
+
if (input === "k" || key.upArrow) {
|
|
79428
|
+
dispatch({ type: "SCROLL_DETAIL_DELTA", delta: -1, totalLines: detailLines.length, viewportHeight: detailViewportHeight });
|
|
79429
|
+
return;
|
|
79430
|
+
}
|
|
79431
|
+
if (input === "h" || key.leftArrow) {
|
|
79432
|
+
dispatch({ type: "SET_FOCUS", target: "side" });
|
|
79433
|
+
return;
|
|
79434
|
+
}
|
|
79435
|
+
if (input === "g") {
|
|
79436
|
+
dispatch({ type: "SCROLL_DETAIL", offset: 0 });
|
|
79437
|
+
return;
|
|
79438
|
+
}
|
|
79439
|
+
if (input === "G") {
|
|
79440
|
+
dispatch({ type: "SCROLL_DETAIL", offset: Math.max(0, detailLines.length - detailViewportHeight) });
|
|
79441
|
+
return;
|
|
79442
|
+
}
|
|
79443
|
+
}
|
|
79444
|
+
if (selectedItem) {
|
|
79445
|
+
const actionMatch = panelActions.find((a) => a.key === input && (!a.condition || a.condition(selectedItem)));
|
|
79446
|
+
if (actionMatch) {
|
|
79447
|
+
executeAction(actionMatch, selectedItem, dispatch, addToast);
|
|
79448
|
+
}
|
|
79449
|
+
}
|
|
79450
|
+
});
|
|
79451
|
+
}
|
|
79452
|
+
|
|
79453
|
+
// src/dashboard/ink/useMouseHandler.ts
|
|
79454
|
+
var import_react31 = __toESM(require_react(), 1);
|
|
79455
|
+
function useMouseHandler(ctx) {
|
|
79456
|
+
const { state, dispatch, panels, panelCounts, currentItems, clampedSelection, sideWidth, sideScroll, detailLines, detailViewportHeight, detailTabs, rows, rotatePhrase } = ctx;
|
|
79457
|
+
return (0, import_react31.useCallback)((event) => {
|
|
79458
|
+
rotatePhrase();
|
|
79459
|
+
if (state.overlay === "filter") return;
|
|
79460
|
+
if (state.overlay) {
|
|
79461
|
+
if (event.type === "click") {
|
|
79462
|
+
dispatch({ type: "SET_OVERLAY", overlay: null });
|
|
79463
|
+
}
|
|
79464
|
+
return;
|
|
79465
|
+
}
|
|
79466
|
+
const { x, y } = event;
|
|
79467
|
+
if (event.type === "scroll") {
|
|
79468
|
+
if (x < sideWidth && sideWidth > 0) {
|
|
79469
|
+
const delta = event.scrollDirection === "down" ? 3 : -3;
|
|
79470
|
+
dispatch({ type: "SCROLL_SIDE", delta, itemCount: currentItems.length });
|
|
79471
|
+
const newIdx = Math.max(0, Math.min(clampedSelection + delta, currentItems.length - 1));
|
|
79472
|
+
sideScroll.setSelected(newIdx);
|
|
79473
|
+
} else {
|
|
79474
|
+
const delta = event.scrollDirection === "down" ? 3 : -3;
|
|
79475
|
+
dispatch({ type: "SCROLL_DETAIL_DELTA", delta, totalLines: detailLines.length, viewportHeight: detailViewportHeight });
|
|
79476
|
+
}
|
|
79477
|
+
return;
|
|
79478
|
+
}
|
|
79479
|
+
if (event.type !== "click" || event.button !== "left") return;
|
|
79480
|
+
if (y === 0) {
|
|
79481
|
+
let col = 0;
|
|
79482
|
+
for (let i = 0; i < panels.length; i++) {
|
|
79483
|
+
const count = panelCounts[i];
|
|
79484
|
+
let countLen = 0;
|
|
79485
|
+
if (count) {
|
|
79486
|
+
countLen = count.running !== void 0 ? ` ${count.running}/${count.total}`.length : ` ${count.total}`.length;
|
|
79487
|
+
}
|
|
79488
|
+
const tabWidth = String(panels[i].shortcutKey).length + panels[i].title.length + 3 + countLen + 1;
|
|
79489
|
+
if (x >= col && x < col + tabWidth) {
|
|
79490
|
+
panels[state.activePanelIndex]?.onDeactivate?.();
|
|
79491
|
+
dispatch({ type: "SWITCH_PANEL", index: i });
|
|
79492
|
+
panels[i]?.onActivate?.();
|
|
79493
|
+
return;
|
|
79494
|
+
}
|
|
79495
|
+
col += tabWidth;
|
|
79496
|
+
}
|
|
79497
|
+
return;
|
|
79498
|
+
}
|
|
79499
|
+
if (y >= rows - 1) return;
|
|
79500
|
+
if (x < sideWidth && sideWidth > 0) {
|
|
79501
|
+
dispatch({ type: "SET_FOCUS", target: "side" });
|
|
79502
|
+
const hasScrollUp = sideScroll.scrollOffset > 0;
|
|
79503
|
+
const itemRow = y - 2 - (hasScrollUp ? 1 : 0);
|
|
79504
|
+
const itemIndex = sideScroll.scrollOffset + itemRow;
|
|
79505
|
+
if (itemIndex >= 0 && itemIndex < currentItems.length) {
|
|
79506
|
+
dispatch({ type: "SELECT_ITEM", index: itemIndex });
|
|
79507
|
+
sideScroll.setSelected(itemIndex);
|
|
79508
|
+
}
|
|
79509
|
+
} else {
|
|
79510
|
+
dispatch({ type: "SET_FOCUS", target: "detail" });
|
|
79511
|
+
if (y === 1 && detailTabs.length > 1) {
|
|
79512
|
+
let col = sideWidth;
|
|
79513
|
+
for (let i = 0; i < detailTabs.length; i++) {
|
|
79514
|
+
const tabWidth = detailTabs[i].label.length + 3;
|
|
79515
|
+
if (x >= col && x < col + tabWidth) {
|
|
79516
|
+
dispatch({ type: "SET_DETAIL_TAB", index: i });
|
|
79517
|
+
return;
|
|
79518
|
+
}
|
|
79519
|
+
col += tabWidth;
|
|
79520
|
+
}
|
|
79521
|
+
}
|
|
79522
|
+
}
|
|
79523
|
+
}, [state.overlay, state.activePanelIndex, sideWidth, currentItems.length, clampedSelection, sideScroll, detailLines.length, detailViewportHeight, panels, panelCounts, detailTabs, rows, rotatePhrase, dispatch]);
|
|
79524
|
+
}
|
|
79525
|
+
|
|
78441
79526
|
// src/dashboard/ink/TabBar.tsx
|
|
78442
79527
|
await init_build2();
|
|
78443
79528
|
var import_jsx_runtime = __toESM(require_jsx_runtime(), 1);
|
|
@@ -78447,8 +79532,14 @@ function TabBar({ panels, activeIndex, layoutMode, phrase, panelCounts }) {
|
|
|
78447
79532
|
const isActive = i === activeIndex;
|
|
78448
79533
|
const count = panelCounts?.[i];
|
|
78449
79534
|
let countStr = "";
|
|
79535
|
+
let countColor;
|
|
78450
79536
|
if (count) {
|
|
78451
79537
|
countStr = count.running !== void 0 ? ` ${count.running}/${count.total}` : ` ${count.total}`;
|
|
79538
|
+
if (count.running !== void 0) {
|
|
79539
|
+
if (count.running === count.total && count.total > 0) countColor = "green";
|
|
79540
|
+
else if (count.running > 0) countColor = "yellow";
|
|
79541
|
+
else countColor = void 0;
|
|
79542
|
+
}
|
|
78452
79543
|
}
|
|
78453
79544
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { marginRight: 1, children: [
|
|
78454
79545
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
@@ -78463,10 +79554,10 @@ function TabBar({ panels, activeIndex, layoutMode, phrase, panelCounts }) {
|
|
|
78463
79554
|
countStr && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
78464
79555
|
Text,
|
|
78465
79556
|
{
|
|
78466
|
-
color: isActive ? "#2B4C7E" : "gray",
|
|
79557
|
+
color: isActive ? countColor || "#2B4C7E" : countColor || "gray",
|
|
78467
79558
|
bold: isActive,
|
|
78468
79559
|
inverse: isActive,
|
|
78469
|
-
dimColor: !isActive,
|
|
79560
|
+
dimColor: !isActive && !countColor,
|
|
78470
79561
|
children: `${countStr} `
|
|
78471
79562
|
}
|
|
78472
79563
|
),
|
|
@@ -78526,11 +79617,15 @@ function SideList({ items, selectedIndex, scrollOffset, focused, width, viewport
|
|
|
78526
79617
|
const rightLabel = item.rightLabel || "";
|
|
78527
79618
|
const rightLen = rightLabel.length;
|
|
78528
79619
|
const leftWidth = innerWidth - rightLen - (rightLen ? 1 : 0);
|
|
78529
|
-
const leftText = `${prefix}${icon}${rest}`;
|
|
78530
|
-
const paddedLeft = leftText.length < leftWidth ? leftText + " ".repeat(leftWidth - leftText.length) : leftText.substring(0, leftWidth);
|
|
78531
79620
|
if (isSelected && focused) {
|
|
78532
|
-
const
|
|
78533
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.
|
|
79621
|
+
const restText = rest.length < leftWidth - prefix.length - 1 ? rest + " ".repeat(leftWidth - prefix.length - 1 - rest.length) : rest.substring(0, leftWidth - prefix.length - 1);
|
|
79622
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { children: [
|
|
79623
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: "#2B4C7E", bold: true, inverse: true, wrap: "truncate", children: ` ${prefix}` }),
|
|
79624
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: item.iconColor || "#2B4C7E", bold: true, inverse: true, children: icon }),
|
|
79625
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: "#2B4C7E", bold: true, inverse: true, wrap: "truncate", children: restText }),
|
|
79626
|
+
rightLen > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: "#2B4C7E", bold: true, inverse: true, children: ` ${rightLabel}` }),
|
|
79627
|
+
!rightLen && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: "#2B4C7E", bold: true, inverse: true, children: " " })
|
|
79628
|
+
] }, item.id);
|
|
78534
79629
|
}
|
|
78535
79630
|
const iconColor = item.iconColor || (isSelected ? "#2B4C7E" : "white");
|
|
78536
79631
|
const textColor = isSelected ? "#2B4C7E" : "white";
|
|
@@ -78542,13 +79637,17 @@ function SideList({ items, selectedIndex, scrollOffset, focused, width, viewport
|
|
|
78542
79637
|
] }, item.id);
|
|
78543
79638
|
}),
|
|
78544
79639
|
hasScrollDown && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: "gray", children: ` \u25BC (${belowCount} more)` }),
|
|
78545
|
-
items.length === 0 && filterString && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { flexDirection: "column", children: [
|
|
78546
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: "
|
|
78547
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: "gray", children: " Press Esc to clear" })
|
|
79640
|
+
items.length === 0 && filterString && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { flexDirection: "column", paddingTop: 1, children: [
|
|
79641
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: "yellow", children: ` \u2717 No matches for "${filterString}"` }),
|
|
79642
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: "gray", dimColor: true, children: " Press Esc to clear filter" })
|
|
78548
79643
|
] }),
|
|
78549
|
-
items.length === 0 && !filterString && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { flexDirection: "column", children: [
|
|
78550
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: "gray", children: ` No ${panelTitle.toLowerCase()} found` }),
|
|
78551
|
-
panelId && EMPTY_HINTS[panelId]
|
|
79644
|
+
items.length === 0 && !filterString && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { flexDirection: "column", paddingTop: 1, children: [
|
|
79645
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: "gray", children: ` \u2500 No ${panelTitle.toLowerCase()} found` }),
|
|
79646
|
+
panelId && EMPTY_HINTS[panelId] && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
79647
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { children: "" }),
|
|
79648
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: "gray", dimColor: true, children: ` ${EMPTY_HINTS[panelId][0]}` }),
|
|
79649
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: "#2B4C7E", bold: true, children: ` ${EMPTY_HINTS[panelId][1]}` })
|
|
79650
|
+
] })
|
|
78552
79651
|
] })
|
|
78553
79652
|
] });
|
|
78554
79653
|
}
|
|
@@ -78558,7 +79657,7 @@ await init_build2();
|
|
|
78558
79657
|
var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1);
|
|
78559
79658
|
function DetailTabBar({ tabs, activeIndex }) {
|
|
78560
79659
|
if (tabs.length <= 1) {
|
|
78561
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Box_default, {});
|
|
79660
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Box_default, { children: tabs.length === 1 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: "gray", dimColor: true, children: ` ${tabs[0].label}` }) });
|
|
78562
79661
|
}
|
|
78563
79662
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Box_default, { children: [
|
|
78564
79663
|
tabs.map((tab2, i) => {
|
|
@@ -78574,7 +79673,7 @@ function DetailTabBar({ tabs, activeIndex }) {
|
|
|
78574
79673
|
) }, tab2.label);
|
|
78575
79674
|
}),
|
|
78576
79675
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Box_default, { flexGrow: 1 }),
|
|
78577
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: "gray", children: "[
|
|
79676
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: "gray", dimColor: true, children: "[/] cycle tabs" })
|
|
78578
79677
|
] });
|
|
78579
79678
|
}
|
|
78580
79679
|
|
|
@@ -78596,9 +79695,9 @@ function DetailPane({ content, scrollOffset, viewportHeight, focused }) {
|
|
|
78596
79695
|
}
|
|
78597
79696
|
|
|
78598
79697
|
// src/dashboard/ink/StatusBar.tsx
|
|
78599
|
-
var
|
|
79698
|
+
var import_react32 = __toESM(require_react(), 1);
|
|
78600
79699
|
await init_build2();
|
|
78601
|
-
var
|
|
79700
|
+
var import_sidekick_docker_shared8 = __toESM(require_dist(), 1);
|
|
78602
79701
|
var import_jsx_runtime5 = __toESM(require_jsx_runtime(), 1);
|
|
78603
79702
|
function formatAgo(date) {
|
|
78604
79703
|
const secs = Math.floor((Date.now() - date.getTime()) / 1e3);
|
|
@@ -78607,72 +79706,89 @@ function formatAgo(date) {
|
|
|
78607
79706
|
const mins = Math.floor(secs / 60);
|
|
78608
79707
|
return { text: `${mins}m ago`, stale: mins >= 1 };
|
|
78609
79708
|
}
|
|
78610
|
-
|
|
78611
|
-
|
|
78612
|
-
(0,
|
|
79709
|
+
var SEP2 = "\u2502";
|
|
79710
|
+
function StatusBar({ daemonConnected, focusTarget, panelActionHints, filterString, containerCount, runningCount, version: version2, matchCount, totalCount, lastRefresh }) {
|
|
79711
|
+
const [, setTick] = (0, import_react32.useState)(0);
|
|
79712
|
+
(0, import_react32.useEffect)(() => {
|
|
78613
79713
|
const timer = setInterval(() => setTick((t) => t + 1), 5e3);
|
|
78614
79714
|
return () => clearInterval(timer);
|
|
78615
79715
|
}, []);
|
|
78616
79716
|
const ago = lastRefresh ? formatAgo(lastRefresh) : null;
|
|
78617
79717
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
|
|
78618
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { bold: true, color: "magenta", children: ` ${
|
|
78619
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "gray", children: ` ${
|
|
78620
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "gray", children:
|
|
79718
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { bold: true, color: "magenta", children: ` \u26A1 ${import_sidekick_docker_shared8.BRAND_INLINE}` }),
|
|
79719
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "gray", dimColor: true, children: ` ${import_sidekick_docker_shared8.BRAND_TAGLINE} v${version2}` }),
|
|
79720
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "gray", dimColor: true, children: ` ${SEP2} ` }),
|
|
78621
79721
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: daemonConnected ? "green" : "red", children: daemonConnected ? `\u25CF ${runningCount ?? 0}/${containerCount ?? 0}` : "\u25CB disconnected" }),
|
|
78622
|
-
ago && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: ago.stale ? "yellow" : "gray", children: `
|
|
78623
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "gray", children:
|
|
78624
|
-
panelActionHints
|
|
78625
|
-
|
|
78626
|
-
|
|
78627
|
-
|
|
78628
|
-
|
|
79722
|
+
ago && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: ago.stale ? "yellow" : "gray", dimColor: !ago.stale, children: ` \u21BB ${ago.text}` }),
|
|
79723
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "gray", dimColor: true, children: ` ${SEP2} ` }),
|
|
79724
|
+
panelActionHints.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
79725
|
+
panelActionHints.map((hint, i) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react32.default.Fragment, { children: [
|
|
79726
|
+
i > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { children: " " }),
|
|
79727
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: hint.destructive ? "red" : "#2B4C7E", children: `${hint.key}:${hint.label}` })
|
|
79728
|
+
] }, hint.key)),
|
|
79729
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "gray", dimColor: true, children: ` ${SEP2} ` })
|
|
78629
79730
|
] }),
|
|
78630
|
-
|
|
79731
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: focusTarget === "side" ? "#2B4C7E" : "gray", bold: focusTarget === "side", children: "\u25C0" }),
|
|
79732
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "gray", dimColor: true, children: "/" }),
|
|
79733
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: focusTarget === "detail" ? "#2B4C7E" : "gray", bold: focusTarget === "detail", children: "\u25B6" }),
|
|
79734
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "gray", dimColor: true, children: " j/k Tab / ? q" }),
|
|
79735
|
+
filterString ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "yellow", bold: true, children: ` \u25C9 "${filterString}"${matchCount !== void 0 && totalCount !== void 0 ? ` ${matchCount}/${totalCount}` : ""}` }) : null
|
|
78631
79736
|
] });
|
|
78632
79737
|
}
|
|
78633
79738
|
|
|
78634
79739
|
// src/dashboard/ink/HelpOverlay.tsx
|
|
78635
79740
|
await init_build2();
|
|
78636
|
-
var
|
|
79741
|
+
var import_sidekick_docker_shared9 = __toESM(require_dist(), 1);
|
|
78637
79742
|
var import_jsx_runtime6 = __toESM(require_jsx_runtime(), 1);
|
|
78638
79743
|
var GLOBAL_BINDINGS = [
|
|
78639
79744
|
{ key: "1-5", label: "Switch panel" },
|
|
78640
79745
|
{ key: "j/k", label: "Navigate / scroll" },
|
|
78641
|
-
{ key: "g/G", label: "
|
|
78642
|
-
{ key: "Tab", label: "Toggle focus
|
|
78643
|
-
{ key: "[/]", label: "
|
|
78644
|
-
{ key: "z", label: "
|
|
79746
|
+
{ key: "g/G", label: "Jump to first / last" },
|
|
79747
|
+
{ key: "Tab", label: "Toggle focus" },
|
|
79748
|
+
{ key: "[/]", label: "Cycle detail tabs" },
|
|
79749
|
+
{ key: "z", label: "Toggle expanded layout" },
|
|
78645
79750
|
{ key: "/", label: "Filter items" },
|
|
78646
|
-
{ key: "x", label: "
|
|
79751
|
+
{ key: "x", label: "Actions menu" },
|
|
78647
79752
|
{ key: "V", label: "Version info" },
|
|
78648
|
-
{ key: "?", label: "
|
|
79753
|
+
{ key: "?", label: "This help" },
|
|
78649
79754
|
{ key: "q", label: "Quit" }
|
|
78650
79755
|
];
|
|
79756
|
+
function KeyBadge({ k }) {
|
|
79757
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "white", backgroundColor: "#2B4C7E", bold: true, children: ` ${k} ` });
|
|
79758
|
+
}
|
|
78651
79759
|
function HelpOverlay({ panels, activePanelIndex, version: version2 }) {
|
|
78652
79760
|
const panel = panels[activePanelIndex];
|
|
78653
79761
|
const actions = panel.getActions();
|
|
78654
79762
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Box_default, { flexDirection: "column", flexGrow: 1, padding: 1, children: [
|
|
78655
79763
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Box_default, { children: [
|
|
78656
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, color: "magenta", children:
|
|
78657
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "gray", children: ` v${version2}` })
|
|
79764
|
+
/* @__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}` }),
|
|
79765
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "gray", dimColor: true, children: ` v${version2}` })
|
|
78658
79766
|
] }),
|
|
78659
79767
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "" }),
|
|
78660
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.
|
|
78661
|
-
|
|
78662
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "
|
|
78663
|
-
|
|
79768
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Box_default, { children: [
|
|
79769
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, color: "yellow", children: "\u2500\u2500 Navigation " }),
|
|
79770
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "gray", dimColor: true, children: "\u2500".repeat(30) })
|
|
79771
|
+
] }),
|
|
79772
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "" }),
|
|
79773
|
+
GLOBAL_BINDINGS.map((b) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Box_default, { children: [
|
|
79774
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Box_default, { width: 10, justifyContent: "flex-end", marginRight: 1, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(KeyBadge, { k: b.key }) }),
|
|
79775
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "gray", children: b.label })
|
|
78664
79776
|
] }, b.key)),
|
|
78665
79777
|
actions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
78666
79778
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "" }),
|
|
78667
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.
|
|
78668
|
-
|
|
78669
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "
|
|
78670
|
-
|
|
78671
|
-
|
|
79779
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Box_default, { children: [
|
|
79780
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, color: "yellow", children: `\u2500\u2500 ${panel.title} Actions ` }),
|
|
79781
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "gray", dimColor: true, children: "\u2500".repeat(24) })
|
|
79782
|
+
] }),
|
|
79783
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "" }),
|
|
79784
|
+
actions.map((a) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Box_default, { children: [
|
|
79785
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Box_default, { width: 10, justifyContent: "flex-end", marginRight: 1, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(KeyBadge, { k: a.key }) }),
|
|
79786
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: a.confirm ? "red" : "gray", children: a.label }),
|
|
79787
|
+
a.confirm && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "red", dimColor: true, children: " \u26A0" })
|
|
78672
79788
|
] }, a.key))
|
|
78673
79789
|
] }),
|
|
78674
79790
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "" }),
|
|
78675
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "gray", children: "Press ? or Esc to close" })
|
|
79791
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "gray", dimColor: true, children: "Press ? or Esc to close" })
|
|
78676
79792
|
] });
|
|
78677
79793
|
}
|
|
78678
79794
|
|
|
@@ -78682,8 +79798,9 @@ var import_jsx_runtime7 = __toESM(require_jsx_runtime(), 1);
|
|
|
78682
79798
|
function FilterOverlay({ filterString, matchCount, totalCount, panelTitle }) {
|
|
78683
79799
|
const countInfo = matchCount !== void 0 && totalCount !== void 0 && panelTitle ? ` ${matchCount} of ${totalCount} ${panelTitle.toLowerCase()}` : "";
|
|
78684
79800
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Box_default, { position: "absolute", marginTop: 1, marginLeft: 1, children: [
|
|
78685
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { backgroundColor: "
|
|
78686
|
-
countInfo && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: "gray", children: countInfo })
|
|
79801
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { backgroundColor: "#2B4C7E", color: "white", bold: true, children: ` \u2315 ${filterString}\u2588 ` }),
|
|
79802
|
+
countInfo && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: "gray", dimColor: true, children: countInfo }),
|
|
79803
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: "gray", dimColor: true, children: " Enter: apply Esc: clear" })
|
|
78687
79804
|
] });
|
|
78688
79805
|
}
|
|
78689
79806
|
|
|
@@ -78699,23 +79816,37 @@ function ContextMenuOverlay({ actions, selectedIndex }) {
|
|
|
78699
79816
|
marginLeft: 2,
|
|
78700
79817
|
flexDirection: "column",
|
|
78701
79818
|
borderStyle: "single",
|
|
78702
|
-
borderColor: "
|
|
79819
|
+
borderColor: "#2B4C7E",
|
|
78703
79820
|
paddingX: 1,
|
|
78704
79821
|
children: [
|
|
78705
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { bold: true, color: "
|
|
79822
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { bold: true, color: "#2B4C7E", children: "\u2630 Actions" }),
|
|
78706
79823
|
actions.map((action, i) => {
|
|
78707
79824
|
const isSelected = i === selectedIndex;
|
|
78708
|
-
|
|
78709
|
-
|
|
78710
|
-
|
|
78711
|
-
|
|
78712
|
-
|
|
78713
|
-
|
|
78714
|
-
|
|
78715
|
-
|
|
78716
|
-
|
|
79825
|
+
const isDanger = !!action.confirm;
|
|
79826
|
+
const color = isSelected ? isDanger ? "red" : "#2B4C7E" : isDanger ? "red" : "white";
|
|
79827
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Box_default, { children: [
|
|
79828
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
79829
|
+
Text,
|
|
79830
|
+
{
|
|
79831
|
+
color,
|
|
79832
|
+
bold: isSelected,
|
|
79833
|
+
inverse: isSelected,
|
|
79834
|
+
children: ` ${action.key} `
|
|
79835
|
+
}
|
|
79836
|
+
),
|
|
79837
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
79838
|
+
Text,
|
|
79839
|
+
{
|
|
79840
|
+
color,
|
|
79841
|
+
bold: isSelected,
|
|
79842
|
+
inverse: isSelected,
|
|
79843
|
+
children: `${action.label}${isDanger ? " \u26A0" : ""} `
|
|
79844
|
+
}
|
|
79845
|
+
)
|
|
79846
|
+
] }, action.key);
|
|
78717
79847
|
}),
|
|
78718
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, {
|
|
79848
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { children: "" }),
|
|
79849
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { color: "gray", dimColor: true, children: "j/k select Enter run Esc close" })
|
|
78719
79850
|
]
|
|
78720
79851
|
}
|
|
78721
79852
|
);
|
|
@@ -78734,16 +79865,22 @@ function ConfirmOverlay({ message }) {
|
|
|
78734
79865
|
flexDirection: "column",
|
|
78735
79866
|
borderStyle: "double",
|
|
78736
79867
|
borderColor: "red",
|
|
78737
|
-
paddingX:
|
|
79868
|
+
paddingX: 2,
|
|
79869
|
+
paddingY: 1,
|
|
78738
79870
|
children: [
|
|
78739
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.
|
|
79871
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Box_default, { children: [
|
|
79872
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { color: "red", bold: true, children: "\u26A0 " }),
|
|
79873
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { bold: true, color: "red", children: "Confirm Action" })
|
|
79874
|
+
] }),
|
|
79875
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { children: "" }),
|
|
78740
79876
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { children: ` ${message}` }),
|
|
79877
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { color: "gray", dimColor: true, children: " This cannot be undone." }),
|
|
78741
79878
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { children: "" }),
|
|
78742
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
78743
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, {
|
|
78744
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { children: "
|
|
78745
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, {
|
|
78746
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { children: "
|
|
79879
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Box_default, { children: [
|
|
79880
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { backgroundColor: "green", color: "white", bold: true, children: " y Yes " }),
|
|
79881
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { children: " " }),
|
|
79882
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { backgroundColor: "red", color: "white", bold: true, children: " n No " }),
|
|
79883
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { color: "gray", dimColor: true, children: " or Esc to cancel" })
|
|
78747
79884
|
] })
|
|
78748
79885
|
]
|
|
78749
79886
|
}
|
|
@@ -78751,37 +79888,53 @@ function ConfirmOverlay({ message }) {
|
|
|
78751
79888
|
}
|
|
78752
79889
|
|
|
78753
79890
|
// src/dashboard/ink/ToastNotification.tsx
|
|
78754
|
-
var
|
|
79891
|
+
var import_react33 = __toESM(require_react(), 1);
|
|
78755
79892
|
await init_build2();
|
|
78756
79893
|
var import_jsx_runtime10 = __toESM(require_jsx_runtime(), 1);
|
|
78757
|
-
var
|
|
79894
|
+
var SEVERITY_COLORS2 = {
|
|
78758
79895
|
error: "red",
|
|
78759
79896
|
warning: "yellow",
|
|
78760
79897
|
info: "#2B4C7E"
|
|
78761
79898
|
};
|
|
78762
79899
|
var SPINNER_FRAMES = "\u280B\u2819\u2839\u2838\u283C\u2834\u2826\u2827";
|
|
78763
79900
|
function ToastNotification({ toast }) {
|
|
78764
|
-
const [frame, setFrame] = (0,
|
|
78765
|
-
(0,
|
|
79901
|
+
const [frame, setFrame] = (0, import_react33.useState)(0);
|
|
79902
|
+
(0, import_react33.useEffect)(() => {
|
|
78766
79903
|
if (toast.severity !== "info") return;
|
|
78767
79904
|
const timer = setInterval(() => {
|
|
78768
79905
|
setFrame((f) => (f + 1) % SPINNER_FRAMES.length);
|
|
78769
79906
|
}, 100);
|
|
78770
79907
|
return () => clearInterval(timer);
|
|
78771
79908
|
}, [toast.id, toast.severity]);
|
|
78772
|
-
const
|
|
78773
|
-
|
|
79909
|
+
const SEVERITY_ICONS = {
|
|
79910
|
+
error: "\u2717",
|
|
79911
|
+
// ✗
|
|
79912
|
+
warning: "\u26A0",
|
|
79913
|
+
// ⚠
|
|
79914
|
+
info: SPINNER_FRAMES[frame]
|
|
79915
|
+
};
|
|
79916
|
+
const icon = SEVERITY_ICONS[toast.severity] || "";
|
|
79917
|
+
const textColor = toast.severity === "warning" ? "black" : "white";
|
|
79918
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Box_default, { position: "absolute", marginTop: 0, justifyContent: "flex-end", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Text, { backgroundColor: SEVERITY_COLORS2[toast.severity] || "white", color: textColor, bold: true, children: ` ${icon} ${toast.message} ` }) });
|
|
78774
79919
|
}
|
|
78775
79920
|
|
|
78776
79921
|
// src/dashboard/ink/TooSmallOverlay.tsx
|
|
78777
79922
|
await init_build2();
|
|
79923
|
+
var import_sidekick_docker_shared10 = __toESM(require_dist(), 1);
|
|
78778
79924
|
var import_jsx_runtime11 = __toESM(require_jsx_runtime(), 1);
|
|
78779
79925
|
function TooSmallOverlay({ columns, rows }) {
|
|
79926
|
+
const needWidth = Math.max(0, 60 - columns);
|
|
79927
|
+
const needHeight = Math.max(0, 15 - rows);
|
|
79928
|
+
const hints = [];
|
|
79929
|
+
if (needWidth > 0) hints.push(`${needWidth} col${needWidth > 1 ? "s" : ""} wider`);
|
|
79930
|
+
if (needHeight > 0) hints.push(`${needHeight} row${needHeight > 1 ? "s" : ""} taller`);
|
|
78780
79931
|
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { flexDirection: "column", justifyContent: "center", alignItems: "center", height: rows, width: columns, children: [
|
|
79932
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { bold: true, color: "magenta", children: `\u26A1 ${import_sidekick_docker_shared10.BRAND_INLINE}` }),
|
|
79933
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { children: "" }),
|
|
78781
79934
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { color: "yellow", bold: true, children: "Terminal too small" }),
|
|
78782
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { color: "gray", children:
|
|
78783
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, {
|
|
78784
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { color: "gray", children: "
|
|
79935
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { color: "gray", children: `${columns}\xD7${rows} \u2192 need ${hints.join(" and ")}` }),
|
|
79936
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { children: "" }),
|
|
79937
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { color: "gray", dimColor: true, children: "Resize to at least 60\xD715 to continue." })
|
|
78785
79938
|
] });
|
|
78786
79939
|
}
|
|
78787
79940
|
|
|
@@ -78870,7 +80023,7 @@ function parseMouseEvent(data) {
|
|
|
78870
80023
|
}
|
|
78871
80024
|
|
|
78872
80025
|
// src/dashboard/ink/mouse/MouseProvider.tsx
|
|
78873
|
-
var
|
|
80026
|
+
var import_react34 = __toESM(require_react(), 1);
|
|
78874
80027
|
await init_build2();
|
|
78875
80028
|
var import_jsx_runtime13 = __toESM(require_jsx_runtime(), 1);
|
|
78876
80029
|
function InputSink() {
|
|
@@ -78879,7 +80032,7 @@ function InputSink() {
|
|
|
78879
80032
|
return null;
|
|
78880
80033
|
}
|
|
78881
80034
|
function MouseProvider({ onMouse, children }) {
|
|
78882
|
-
(0,
|
|
80035
|
+
(0, import_react34.useEffect)(() => {
|
|
78883
80036
|
enableMouse();
|
|
78884
80037
|
const handler = (data) => {
|
|
78885
80038
|
const event = parseMouseEvent(data);
|
|
@@ -78902,29 +80055,40 @@ function MouseProvider({ onMouse, children }) {
|
|
|
78902
80055
|
] });
|
|
78903
80056
|
}
|
|
78904
80057
|
|
|
78905
|
-
// src/dashboard/ink/
|
|
78906
|
-
var import_react34 = __toESM(require_react(), 1);
|
|
80058
|
+
// src/dashboard/ink/LogFilterOverlay.tsx
|
|
78907
80059
|
await init_build2();
|
|
78908
|
-
var import_sidekick_docker_shared5 = __toESM(require_dist(), 1);
|
|
78909
80060
|
var import_jsx_runtime14 = __toESM(require_jsx_runtime(), 1);
|
|
80061
|
+
function LogFilterOverlay({ filterString, filterMode }) {
|
|
80062
|
+
const modeLabel = filterMode === "exact" ? "exact" : "fuzzy";
|
|
80063
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(Box_default, { position: "absolute", marginTop: 1, marginLeft: 1, children: [
|
|
80064
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Text, { backgroundColor: "#2B4C7E", color: "white", bold: true, children: ` Log filter (${modeLabel}): ${filterString}\u2588 ` }),
|
|
80065
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Text, { color: "gray", children: " Tab: toggle mode Enter: apply Esc: clear" })
|
|
80066
|
+
] });
|
|
80067
|
+
}
|
|
80068
|
+
|
|
80069
|
+
// src/dashboard/ink/VersionOverlay.tsx
|
|
80070
|
+
var import_react35 = __toESM(require_react(), 1);
|
|
80071
|
+
await init_build2();
|
|
80072
|
+
var import_sidekick_docker_shared11 = __toESM(require_dist(), 1);
|
|
80073
|
+
var import_jsx_runtime15 = __toESM(require_jsx_runtime(), 1);
|
|
78910
80074
|
function VersionOverlay({ version: version2 }) {
|
|
78911
|
-
const phrase =
|
|
78912
|
-
return /* @__PURE__ */ (0,
|
|
78913
|
-
/* @__PURE__ */ (0,
|
|
78914
|
-
/* @__PURE__ */ (0,
|
|
78915
|
-
|
|
78916
|
-
|
|
78917
|
-
|
|
78918
|
-
|
|
78919
|
-
/* @__PURE__ */ (0,
|
|
78920
|
-
/* @__PURE__ */ (0,
|
|
78921
|
-
/* @__PURE__ */ (0,
|
|
78922
|
-
/* @__PURE__ */ (0,
|
|
80075
|
+
const phrase = import_react35.default.useMemo(() => (0, import_sidekick_docker_shared11.getRandomPhrase)(), []);
|
|
80076
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Box_default, { flexDirection: "column", flexGrow: 1, padding: 1, children: [
|
|
80077
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Text, { bold: true, color: "magenta", children: `\u26A1 ${import_sidekick_docker_shared11.BRAND_INLINE}` }),
|
|
80078
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Text, { color: "#2B4C7E", bold: true, children: `${import_sidekick_docker_shared11.BRAND_TAGLINE} v${version2}` }),
|
|
80079
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Text, { children: "" }),
|
|
80080
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Text, { color: "gray", dimColor: true, children: "\u2500".repeat(40) }),
|
|
80081
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Text, { children: "" }),
|
|
80082
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Text, { color: "gray", italic: true, children: ` "${phrase}"` }),
|
|
80083
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Text, { children: "" }),
|
|
80084
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Text, { color: "gray", dimColor: true, children: "\u2500".repeat(40) }),
|
|
80085
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Text, { children: "" }),
|
|
80086
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Text, { color: "gray", dimColor: true, children: "Press V or Esc to close" })
|
|
78923
80087
|
] });
|
|
78924
80088
|
}
|
|
78925
80089
|
|
|
78926
80090
|
// src/dashboard/ink/Dashboard.tsx
|
|
78927
|
-
var
|
|
80091
|
+
var import_sidekick_docker_shared12 = __toESM(require_dist(), 1);
|
|
78928
80092
|
|
|
78929
80093
|
// src/dashboard/ExecManager.ts
|
|
78930
80094
|
var ExecManager = class {
|
|
@@ -78981,10 +80145,12 @@ var ExecManager = class {
|
|
|
78981
80145
|
};
|
|
78982
80146
|
|
|
78983
80147
|
// src/dashboard/ink/Dashboard.tsx
|
|
78984
|
-
var
|
|
80148
|
+
var import_jsx_runtime16 = __toESM(require_jsx_runtime(), 1);
|
|
78985
80149
|
var SIDE_PANEL_WIDTH = 28;
|
|
78986
80150
|
var MIN_SCREEN_WIDTH = 60;
|
|
78987
80151
|
var MIN_SCREEN_HEIGHT = 15;
|
|
80152
|
+
var RESERVED_UI_ROWS = 5;
|
|
80153
|
+
var TOAST_DURATIONS = { error: 4e3, warning: 3e3, info: 2e3 };
|
|
78988
80154
|
function reducer(state, action) {
|
|
78989
80155
|
switch (action.type) {
|
|
78990
80156
|
case "SWITCH_PANEL":
|
|
@@ -79061,6 +80227,10 @@ function reducer(state, action) {
|
|
|
79061
80227
|
}
|
|
79062
80228
|
case "EXEC_END":
|
|
79063
80229
|
return { ...state, overlay: null, execContainerId: null, execContainerName: "", execOutputLines: [] };
|
|
80230
|
+
case "SET_LOG_FILTER":
|
|
80231
|
+
return { ...state, logFilterString: action.value };
|
|
80232
|
+
case "TOGGLE_LOG_FILTER_MODE":
|
|
80233
|
+
return { ...state, logFilterMode: state.logFilterMode === "exact" ? "fuzzy" : "exact" };
|
|
79064
80234
|
default:
|
|
79065
80235
|
return state;
|
|
79066
80236
|
}
|
|
@@ -79080,28 +80250,29 @@ var initialState = {
|
|
|
79080
80250
|
confirmMessage: "",
|
|
79081
80251
|
execOutputLines: [],
|
|
79082
80252
|
execContainerId: null,
|
|
79083
|
-
execContainerName: ""
|
|
80253
|
+
execContainerName: "",
|
|
80254
|
+
logFilterString: "",
|
|
80255
|
+
logFilterMode: "exact"
|
|
79084
80256
|
};
|
|
79085
80257
|
function Dashboard({ panels, metrics, onSelectionChange, execTriggerRef, onExecFallback }) {
|
|
79086
|
-
const [state, dispatch] = (0,
|
|
79087
|
-
const { exit } = use_app_default();
|
|
80258
|
+
const [state, dispatch] = (0, import_react36.useReducer)(reducer, initialState);
|
|
79088
80259
|
const { columns, rows } = useTerminalSize();
|
|
79089
|
-
const toastIdRef = (0,
|
|
79090
|
-
const execManagerRef = (0,
|
|
79091
|
-
const [phrase, setPhrase] =
|
|
79092
|
-
const phraseTimerRef = (0,
|
|
79093
|
-
const rotatePhrase = (0,
|
|
79094
|
-
setPhrase((0,
|
|
80260
|
+
const toastIdRef = (0, import_react36.useRef)(0);
|
|
80261
|
+
const execManagerRef = (0, import_react36.useRef)(null);
|
|
80262
|
+
const [phrase, setPhrase] = import_react36.default.useState(() => (0, import_sidekick_docker_shared12.getRandomPhrase)());
|
|
80263
|
+
const phraseTimerRef = (0, import_react36.useRef)(null);
|
|
80264
|
+
const rotatePhrase = (0, import_react36.useCallback)(() => {
|
|
80265
|
+
setPhrase((0, import_sidekick_docker_shared12.getRandomPhrase)());
|
|
79095
80266
|
if (phraseTimerRef.current) clearTimeout(phraseTimerRef.current);
|
|
79096
80267
|
phraseTimerRef.current = setTimeout(rotatePhrase, 7e3);
|
|
79097
80268
|
}, []);
|
|
79098
|
-
(0,
|
|
80269
|
+
(0, import_react36.useEffect)(() => {
|
|
79099
80270
|
phraseTimerRef.current = setTimeout(rotatePhrase, 7e3);
|
|
79100
80271
|
return () => {
|
|
79101
80272
|
if (phraseTimerRef.current) clearTimeout(phraseTimerRef.current);
|
|
79102
80273
|
};
|
|
79103
80274
|
}, [rotatePhrase]);
|
|
79104
|
-
(0,
|
|
80275
|
+
(0, import_react36.useEffect)(() => {
|
|
79105
80276
|
if (!execTriggerRef) return;
|
|
79106
80277
|
execTriggerRef.current = (containerId, containerName) => {
|
|
79107
80278
|
const manager = new ExecManager();
|
|
@@ -79136,7 +80307,7 @@ function Dashboard({ panels, metrics, onSelectionChange, execTriggerRef, onExecF
|
|
|
79136
80307
|
execTriggerRef.current = null;
|
|
79137
80308
|
};
|
|
79138
80309
|
}, [execTriggerRef, onExecFallback, columns, rows]);
|
|
79139
|
-
(0,
|
|
80310
|
+
(0, import_react36.useEffect)(() => {
|
|
79140
80311
|
if (state.overlay !== "exec") return;
|
|
79141
80312
|
const handler = (data) => {
|
|
79142
80313
|
if (data.length === 1 && data[0] === 29) {
|
|
@@ -79153,22 +80324,23 @@ function Dashboard({ panels, metrics, onSelectionChange, execTriggerRef, onExecF
|
|
|
79153
80324
|
process.stdin.removeListener("data", handler);
|
|
79154
80325
|
};
|
|
79155
80326
|
}, [state.overlay]);
|
|
79156
|
-
(0,
|
|
80327
|
+
(0, import_react36.useEffect)(() => {
|
|
79157
80328
|
if (state.overlay === "exec" && execManagerRef.current) {
|
|
79158
80329
|
execManagerRef.current.resize(columns, rows);
|
|
79159
80330
|
}
|
|
79160
80331
|
}, [columns, rows, state.overlay]);
|
|
79161
|
-
const addToast = (0,
|
|
79162
|
-
const durations = { error: 4e3, warning: 3e3, info: 2e3 };
|
|
80332
|
+
const addToast = (0, import_react36.useCallback)((message, severity) => {
|
|
79163
80333
|
const id = ++toastIdRef.current;
|
|
79164
|
-
dispatch({ type: "ADD_TOAST", toast: { id, message, severity, expiresAt: Date.now() +
|
|
79165
|
-
setTimeout(() => dispatch({ type: "REMOVE_TOAST", id }),
|
|
80334
|
+
dispatch({ type: "ADD_TOAST", toast: { id, message, severity, expiresAt: Date.now() + TOAST_DURATIONS[severity] } });
|
|
80335
|
+
setTimeout(() => dispatch({ type: "REMOVE_TOAST", id }), TOAST_DURATIONS[severity]);
|
|
79166
80336
|
}, []);
|
|
79167
80337
|
const panel = panels[state.activePanelIndex];
|
|
79168
80338
|
const tooSmall = columns < MIN_SCREEN_WIDTH || rows < MIN_SCREEN_HEIGHT;
|
|
79169
80339
|
const sideWidth = state.layoutMode === "expanded" ? 0 : SIDE_PANEL_WIDTH;
|
|
79170
|
-
const
|
|
79171
|
-
|
|
80340
|
+
const allItems = panel.getItems(metrics);
|
|
80341
|
+
const totalItemCount = allItems.length;
|
|
80342
|
+
const currentItems = (() => {
|
|
80343
|
+
let items = allItems;
|
|
79172
80344
|
if (state.filterString) {
|
|
79173
80345
|
const f = state.filterString.toLowerCase();
|
|
79174
80346
|
items = items.filter((it) => {
|
|
@@ -79178,361 +80350,101 @@ function Dashboard({ panels, metrics, onSelectionChange, execTriggerRef, onExecF
|
|
|
79178
80350
|
}
|
|
79179
80351
|
items.sort((a, b) => a.sortKey - b.sortKey);
|
|
79180
80352
|
return items;
|
|
79181
|
-
}
|
|
79182
|
-
const currentItems = getFilteredItems();
|
|
80353
|
+
})();
|
|
79183
80354
|
const clampedSelection = Math.min(state.selectedItemIndex, Math.max(0, currentItems.length - 1));
|
|
79184
80355
|
if (clampedSelection !== state.selectedItemIndex && currentItems.length > 0) {
|
|
79185
80356
|
dispatch({ type: "SELECT_ITEM", index: clampedSelection });
|
|
79186
80357
|
}
|
|
79187
|
-
const sideViewportHeight = Math.max(1, rows -
|
|
80358
|
+
const sideViewportHeight = Math.max(1, rows - RESERVED_UI_ROWS);
|
|
79188
80359
|
const sideScroll = useWindowedScroll({ totalItems: currentItems.length, viewportHeight: sideViewportHeight });
|
|
79189
|
-
(0,
|
|
80360
|
+
(0, import_react36.useEffect)(() => {
|
|
79190
80361
|
if (sideScroll.selectedIndex !== state.selectedItemIndex) {
|
|
79191
80362
|
sideScroll.setSelected(state.selectedItemIndex);
|
|
79192
80363
|
}
|
|
79193
80364
|
}, [state.selectedItemIndex]);
|
|
79194
80365
|
const selectedItem = currentItems[clampedSelection];
|
|
79195
|
-
(0,
|
|
80366
|
+
(0, import_react36.useEffect)(() => {
|
|
79196
80367
|
onSelectionChange?.(panel.id, selectedItem?.id ?? null);
|
|
79197
80368
|
}, [panel.id, selectedItem?.id]);
|
|
79198
80369
|
const detailTabs = panel.detailTabs;
|
|
79199
80370
|
const tabIdx = Math.min(state.detailTabIndex, detailTabs.length - 1);
|
|
80371
|
+
const enrichedMetrics = {
|
|
80372
|
+
...metrics,
|
|
80373
|
+
logFilterString: state.logFilterString,
|
|
80374
|
+
logFilterMode: state.logFilterMode
|
|
80375
|
+
};
|
|
79200
80376
|
let detailContent = "";
|
|
79201
80377
|
if (selectedItem && detailTabs.length > 0 && tabIdx >= 0) {
|
|
79202
|
-
detailContent = detailTabs[tabIdx].render(selectedItem,
|
|
80378
|
+
detailContent = detailTabs[tabIdx].render(selectedItem, enrichedMetrics);
|
|
79203
80379
|
} else if (!selectedItem) {
|
|
79204
80380
|
detailContent = "(no item selected)";
|
|
79205
80381
|
}
|
|
79206
80382
|
const detailLines = detailContent.split("\n");
|
|
79207
|
-
const detailViewportHeight = Math.max(1, rows -
|
|
80383
|
+
const detailViewportHeight = Math.max(1, rows - RESERVED_UI_ROWS);
|
|
79208
80384
|
const activeTab = detailTabs[tabIdx];
|
|
79209
80385
|
const shouldAutoScroll = activeTab?.autoScrollBottom ?? false;
|
|
79210
|
-
(0,
|
|
80386
|
+
(0, import_react36.useEffect)(() => {
|
|
79211
80387
|
if (shouldAutoScroll && detailLines.length > detailViewportHeight) {
|
|
79212
80388
|
dispatch({ type: "SCROLL_DETAIL", offset: detailLines.length - detailViewportHeight });
|
|
79213
80389
|
}
|
|
79214
80390
|
}, [shouldAutoScroll, detailLines.length, detailViewportHeight]);
|
|
79215
|
-
const
|
|
79216
|
-
|
|
79217
|
-
|
|
79218
|
-
}, [panel, selectedItem]);
|
|
79219
|
-
const contextActions = state.overlay === "context-menu" ? getContextActions() : [];
|
|
79220
|
-
const handleMouse = (0, import_react35.useCallback)((event) => {
|
|
79221
|
-
rotatePhrase();
|
|
79222
|
-
if (state.overlay === "filter") return;
|
|
79223
|
-
if (state.overlay) {
|
|
79224
|
-
if (event.type === "click") {
|
|
79225
|
-
dispatch({ type: "SET_OVERLAY", overlay: null });
|
|
79226
|
-
}
|
|
79227
|
-
return;
|
|
79228
|
-
}
|
|
79229
|
-
const { x, y } = event;
|
|
79230
|
-
if (event.type === "scroll") {
|
|
79231
|
-
if (x < sideWidth && sideWidth > 0) {
|
|
79232
|
-
const delta = event.scrollDirection === "down" ? 3 : -3;
|
|
79233
|
-
dispatch({ type: "SCROLL_SIDE", delta, itemCount: currentItems.length });
|
|
79234
|
-
const newIdx = Math.max(0, Math.min(clampedSelection + delta, currentItems.length - 1));
|
|
79235
|
-
sideScroll.setSelected(newIdx);
|
|
79236
|
-
} else {
|
|
79237
|
-
const delta = event.scrollDirection === "down" ? 3 : -3;
|
|
79238
|
-
dispatch({ type: "SCROLL_DETAIL_DELTA", delta, totalLines: detailLines.length, viewportHeight: detailViewportHeight });
|
|
79239
|
-
}
|
|
79240
|
-
return;
|
|
79241
|
-
}
|
|
79242
|
-
if (event.type !== "click" || event.button !== "left") return;
|
|
79243
|
-
if (y === 0) {
|
|
79244
|
-
let col = 0;
|
|
79245
|
-
for (let i = 0; i < panels.length; i++) {
|
|
79246
|
-
const count = panelCounts[i];
|
|
79247
|
-
let countLen = 0;
|
|
79248
|
-
if (count) {
|
|
79249
|
-
countLen = count.running !== void 0 ? ` ${count.running}/${count.total}`.length : ` ${count.total}`.length;
|
|
79250
|
-
}
|
|
79251
|
-
const tabWidth = String(panels[i].shortcutKey).length + panels[i].title.length + 3 + countLen + 1;
|
|
79252
|
-
if (x >= col && x < col + tabWidth) {
|
|
79253
|
-
panels[state.activePanelIndex]?.onDeactivate?.();
|
|
79254
|
-
dispatch({ type: "SWITCH_PANEL", index: i });
|
|
79255
|
-
panels[i]?.onActivate?.();
|
|
79256
|
-
return;
|
|
79257
|
-
}
|
|
79258
|
-
col += tabWidth;
|
|
79259
|
-
}
|
|
79260
|
-
return;
|
|
79261
|
-
}
|
|
79262
|
-
if (y >= rows - 1) return;
|
|
79263
|
-
if (x < sideWidth && sideWidth > 0) {
|
|
79264
|
-
dispatch({ type: "SET_FOCUS", target: "side" });
|
|
79265
|
-
const hasScrollUp = sideScroll.scrollOffset > 0;
|
|
79266
|
-
const itemRow = y - 2 - (hasScrollUp ? 1 : 0);
|
|
79267
|
-
const itemIndex = sideScroll.scrollOffset + itemRow;
|
|
79268
|
-
if (itemIndex >= 0 && itemIndex < currentItems.length) {
|
|
79269
|
-
dispatch({ type: "SELECT_ITEM", index: itemIndex });
|
|
79270
|
-
sideScroll.setSelected(itemIndex);
|
|
79271
|
-
}
|
|
79272
|
-
} else {
|
|
79273
|
-
dispatch({ type: "SET_FOCUS", target: "detail" });
|
|
79274
|
-
if (y === 1 && detailTabs.length > 1) {
|
|
79275
|
-
let col = sideWidth;
|
|
79276
|
-
for (let i = 0; i < detailTabs.length; i++) {
|
|
79277
|
-
const tabWidth = detailTabs[i].label.length + 3;
|
|
79278
|
-
if (x >= col && x < col + tabWidth) {
|
|
79279
|
-
dispatch({ type: "SET_DETAIL_TAB", index: i });
|
|
79280
|
-
return;
|
|
79281
|
-
}
|
|
79282
|
-
col += tabWidth;
|
|
79283
|
-
}
|
|
79284
|
-
}
|
|
79285
|
-
}
|
|
79286
|
-
}, [state.overlay, state.activePanelIndex, sideWidth, currentItems.length, clampedSelection, sideScroll, detailLines.length, detailViewportHeight, panels, detailTabs, rows, rotatePhrase]);
|
|
79287
|
-
use_input_default((input, key) => {
|
|
79288
|
-
if (state.overlay === "exec") return;
|
|
79289
|
-
rotatePhrase();
|
|
79290
|
-
if (input === "q" || key.ctrl && input === "c") {
|
|
79291
|
-
if (state.overlay) {
|
|
79292
|
-
dispatch({ type: "SET_OVERLAY", overlay: null });
|
|
79293
|
-
return;
|
|
79294
|
-
}
|
|
79295
|
-
exit();
|
|
79296
|
-
return;
|
|
79297
|
-
}
|
|
79298
|
-
if (state.overlay === "confirm") {
|
|
79299
|
-
if (input === "y" || input === "Y") {
|
|
79300
|
-
state.confirmAction?.();
|
|
79301
|
-
dispatch({ type: "SET_CONFIRM", action: null, message: "" });
|
|
79302
|
-
return;
|
|
79303
|
-
}
|
|
79304
|
-
if (input === "n" || input === "N" || key.escape) {
|
|
79305
|
-
dispatch({ type: "SET_CONFIRM", action: null, message: "" });
|
|
79306
|
-
return;
|
|
79307
|
-
}
|
|
79308
|
-
return;
|
|
79309
|
-
}
|
|
79310
|
-
if (state.overlay === "filter") {
|
|
79311
|
-
if (key.escape) {
|
|
79312
|
-
if (state.filterString) addToast("Filter cleared", "info");
|
|
79313
|
-
dispatch({ type: "SET_FILTER", value: "" });
|
|
79314
|
-
dispatch({ type: "SET_OVERLAY", overlay: null });
|
|
79315
|
-
return;
|
|
79316
|
-
}
|
|
79317
|
-
if (key.return) {
|
|
79318
|
-
if (state.filterString) addToast(`Filter: "${state.filterString}"`, "info");
|
|
79319
|
-
dispatch({ type: "SET_OVERLAY", overlay: null });
|
|
79320
|
-
return;
|
|
79321
|
-
}
|
|
79322
|
-
if (key.backspace || key.delete) {
|
|
79323
|
-
dispatch({ type: "SET_FILTER", value: state.filterString.slice(0, -1) });
|
|
79324
|
-
return;
|
|
79325
|
-
}
|
|
79326
|
-
if (input && !key.ctrl && !key.meta) {
|
|
79327
|
-
dispatch({ type: "SET_FILTER", value: state.filterString + input });
|
|
79328
|
-
return;
|
|
79329
|
-
}
|
|
79330
|
-
return;
|
|
79331
|
-
}
|
|
79332
|
-
if (state.overlay === "context-menu") {
|
|
79333
|
-
if (key.escape) {
|
|
79334
|
-
dispatch({ type: "SET_OVERLAY", overlay: null });
|
|
79335
|
-
return;
|
|
79336
|
-
}
|
|
79337
|
-
if (input === "j" || key.downArrow) {
|
|
79338
|
-
dispatch({ type: "CONTEXT_MENU_NAV", delta: 1, itemCount: contextActions.length });
|
|
79339
|
-
return;
|
|
79340
|
-
}
|
|
79341
|
-
if (input === "k" || key.upArrow) {
|
|
79342
|
-
dispatch({ type: "CONTEXT_MENU_NAV", delta: -1, itemCount: contextActions.length });
|
|
79343
|
-
return;
|
|
79344
|
-
}
|
|
79345
|
-
if (key.return) {
|
|
79346
|
-
const action = contextActions[state.contextMenuIndex];
|
|
79347
|
-
if (action && selectedItem) {
|
|
79348
|
-
if (action.confirm) {
|
|
79349
|
-
dispatch({ type: "SET_CONFIRM", action: () => {
|
|
79350
|
-
action.handler(selectedItem);
|
|
79351
|
-
addToast(action.label, "info");
|
|
79352
|
-
}, message: action.confirmMessage || "Are you sure?" });
|
|
79353
|
-
} else {
|
|
79354
|
-
action.handler(selectedItem);
|
|
79355
|
-
addToast(action.label, "info");
|
|
79356
|
-
}
|
|
79357
|
-
dispatch({ type: "SET_OVERLAY", overlay: null });
|
|
79358
|
-
}
|
|
79359
|
-
return;
|
|
79360
|
-
}
|
|
79361
|
-
const match = contextActions.find((a) => a.key === input);
|
|
79362
|
-
if (match && selectedItem) {
|
|
79363
|
-
if (match.confirm) {
|
|
79364
|
-
dispatch({ type: "SET_CONFIRM", action: () => {
|
|
79365
|
-
match.handler(selectedItem);
|
|
79366
|
-
addToast(match.label, "info");
|
|
79367
|
-
}, message: match.confirmMessage || "Are you sure?" });
|
|
79368
|
-
} else {
|
|
79369
|
-
match.handler(selectedItem);
|
|
79370
|
-
addToast(match.label, "info");
|
|
79371
|
-
}
|
|
79372
|
-
dispatch({ type: "SET_OVERLAY", overlay: null });
|
|
79373
|
-
}
|
|
79374
|
-
return;
|
|
79375
|
-
}
|
|
79376
|
-
if (state.overlay === "help") {
|
|
79377
|
-
if (key.escape || input === "?") {
|
|
79378
|
-
dispatch({ type: "SET_OVERLAY", overlay: null });
|
|
79379
|
-
}
|
|
79380
|
-
return;
|
|
79381
|
-
}
|
|
79382
|
-
if (state.overlay === "version") {
|
|
79383
|
-
if (key.escape || input === "V") {
|
|
79384
|
-
dispatch({ type: "SET_OVERLAY", overlay: null });
|
|
79385
|
-
}
|
|
79386
|
-
return;
|
|
79387
|
-
}
|
|
79388
|
-
if (key.escape) {
|
|
79389
|
-
if (state.filterString) {
|
|
79390
|
-
dispatch({ type: "SET_FILTER", value: "" });
|
|
79391
|
-
return;
|
|
79392
|
-
}
|
|
79393
|
-
if (state.focusTarget === "detail") {
|
|
79394
|
-
dispatch({ type: "SET_FOCUS", target: "side" });
|
|
79395
|
-
return;
|
|
79396
|
-
}
|
|
79397
|
-
return;
|
|
79398
|
-
}
|
|
79399
|
-
if (input === "?") {
|
|
79400
|
-
dispatch({ type: "SET_OVERLAY", overlay: "help" });
|
|
79401
|
-
return;
|
|
79402
|
-
}
|
|
79403
|
-
if (input === "V") {
|
|
79404
|
-
dispatch({ type: "SET_OVERLAY", overlay: "version" });
|
|
79405
|
-
return;
|
|
79406
|
-
}
|
|
79407
|
-
const num = parseInt(input, 10);
|
|
79408
|
-
if (num >= 1 && num <= panels.length) {
|
|
79409
|
-
panels[state.activePanelIndex]?.onDeactivate?.();
|
|
79410
|
-
dispatch({ type: "SWITCH_PANEL", index: num - 1 });
|
|
79411
|
-
panels[num - 1]?.onActivate?.();
|
|
79412
|
-
return;
|
|
79413
|
-
}
|
|
79414
|
-
if (key.tab) {
|
|
79415
|
-
dispatch({ type: "TOGGLE_FOCUS" });
|
|
79416
|
-
return;
|
|
79417
|
-
}
|
|
79418
|
-
if (input === "z") {
|
|
79419
|
-
dispatch({ type: "CYCLE_LAYOUT" });
|
|
79420
|
-
addToast(`Layout: ${state.layoutMode === "normal" ? "Expanded" : "Normal"}`, "info");
|
|
79421
|
-
return;
|
|
79422
|
-
}
|
|
79423
|
-
if (input === "/") {
|
|
79424
|
-
dispatch({ type: "SET_OVERLAY", overlay: "filter" });
|
|
79425
|
-
return;
|
|
79426
|
-
}
|
|
79427
|
-
if (input === "x") {
|
|
79428
|
-
if (selectedItem && panel.getActions().length > 0) {
|
|
79429
|
-
dispatch({ type: "SET_OVERLAY", overlay: "context-menu" });
|
|
79430
|
-
}
|
|
79431
|
-
return;
|
|
79432
|
-
}
|
|
79433
|
-
if (input === "[") {
|
|
79434
|
-
dispatch({ type: "CYCLE_DETAIL_TAB", direction: -1, tabCount: detailTabs.length });
|
|
79435
|
-
return;
|
|
79436
|
-
}
|
|
79437
|
-
if (input === "]") {
|
|
79438
|
-
dispatch({ type: "CYCLE_DETAIL_TAB", direction: 1, tabCount: detailTabs.length });
|
|
79439
|
-
return;
|
|
79440
|
-
}
|
|
79441
|
-
if (state.focusTarget === "side") {
|
|
79442
|
-
if (input === "j" || key.downArrow) {
|
|
79443
|
-
if (clampedSelection < currentItems.length - 1) {
|
|
79444
|
-
dispatch({ type: "SELECT_ITEM", index: clampedSelection + 1 });
|
|
79445
|
-
sideScroll.selectNext();
|
|
79446
|
-
}
|
|
79447
|
-
return;
|
|
79448
|
-
}
|
|
79449
|
-
if (input === "k" || key.upArrow) {
|
|
79450
|
-
if (clampedSelection > 0) {
|
|
79451
|
-
dispatch({ type: "SELECT_ITEM", index: clampedSelection - 1 });
|
|
79452
|
-
sideScroll.selectPrev();
|
|
79453
|
-
}
|
|
79454
|
-
return;
|
|
79455
|
-
}
|
|
79456
|
-
if (input === "g") {
|
|
79457
|
-
dispatch({ type: "SELECT_ITEM", index: 0 });
|
|
79458
|
-
sideScroll.selectFirst();
|
|
79459
|
-
return;
|
|
79460
|
-
}
|
|
79461
|
-
if (input === "G") {
|
|
79462
|
-
dispatch({ type: "SELECT_ITEM", index: Math.max(0, currentItems.length - 1) });
|
|
79463
|
-
sideScroll.selectLast();
|
|
79464
|
-
return;
|
|
79465
|
-
}
|
|
79466
|
-
if (key.return) {
|
|
79467
|
-
dispatch({ type: "SET_FOCUS", target: "detail" });
|
|
79468
|
-
return;
|
|
79469
|
-
}
|
|
79470
|
-
}
|
|
79471
|
-
if (state.focusTarget === "detail") {
|
|
79472
|
-
if (input === "j" || key.downArrow) {
|
|
79473
|
-
dispatch({ type: "SCROLL_DETAIL_DELTA", delta: 1, totalLines: detailLines.length, viewportHeight: detailViewportHeight });
|
|
79474
|
-
return;
|
|
79475
|
-
}
|
|
79476
|
-
if (input === "k" || key.upArrow) {
|
|
79477
|
-
dispatch({ type: "SCROLL_DETAIL_DELTA", delta: -1, totalLines: detailLines.length, viewportHeight: detailViewportHeight });
|
|
79478
|
-
return;
|
|
79479
|
-
}
|
|
79480
|
-
if (input === "h" || key.leftArrow) {
|
|
79481
|
-
dispatch({ type: "SET_FOCUS", target: "side" });
|
|
79482
|
-
return;
|
|
79483
|
-
}
|
|
79484
|
-
if (input === "g") {
|
|
79485
|
-
dispatch({ type: "SCROLL_DETAIL", offset: 0 });
|
|
79486
|
-
return;
|
|
79487
|
-
}
|
|
79488
|
-
if (input === "G") {
|
|
79489
|
-
dispatch({ type: "SCROLL_DETAIL", offset: Math.max(0, detailLines.length - detailViewportHeight) });
|
|
79490
|
-
return;
|
|
79491
|
-
}
|
|
79492
|
-
}
|
|
79493
|
-
if (selectedItem) {
|
|
79494
|
-
const actions = panel.getActions();
|
|
79495
|
-
const actionMatch = actions.find((a) => a.key === input && (!a.condition || a.condition(selectedItem)));
|
|
79496
|
-
if (actionMatch) {
|
|
79497
|
-
if (actionMatch.confirm) {
|
|
79498
|
-
dispatch({ type: "SET_CONFIRM", action: () => {
|
|
79499
|
-
actionMatch.handler(selectedItem);
|
|
79500
|
-
addToast(actionMatch.label, "info");
|
|
79501
|
-
}, message: actionMatch.confirmMessage || "Are you sure?" });
|
|
79502
|
-
} else {
|
|
79503
|
-
actionMatch.handler(selectedItem);
|
|
79504
|
-
addToast(actionMatch.label, "info");
|
|
79505
|
-
}
|
|
79506
|
-
}
|
|
79507
|
-
}
|
|
79508
|
-
});
|
|
79509
|
-
if (tooSmall) {
|
|
79510
|
-
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TooSmallOverlay, { columns, rows });
|
|
79511
|
-
}
|
|
80391
|
+
const panelActions = panel.getActions();
|
|
80392
|
+
const applicableActions = selectedItem ? panelActions.filter((a) => !a.condition || a.condition(selectedItem)) : [];
|
|
80393
|
+
const contextActions = state.overlay === "context-menu" ? applicableActions : [];
|
|
79512
80394
|
const runningCount = metrics.containers.filter((c) => c.state === "running").length;
|
|
79513
80395
|
const panelCounts = panels.map((p) => {
|
|
79514
|
-
const items = p.getItems(metrics);
|
|
79515
80396
|
if (p.id === "containers") {
|
|
79516
|
-
|
|
79517
|
-
const d = it.data;
|
|
79518
|
-
return d?.state === "running";
|
|
79519
|
-
}).length;
|
|
79520
|
-
return { total: items.length, running };
|
|
80397
|
+
return { total: metrics.containers.length, running: runningCount };
|
|
79521
80398
|
}
|
|
79522
80399
|
if (p.id === "services") {
|
|
79523
|
-
const meaningful =
|
|
80400
|
+
const meaningful = metrics.composeProjects.reduce((sum, proj) => sum + proj.services.length, 0);
|
|
79524
80401
|
return { total: meaningful };
|
|
79525
80402
|
}
|
|
80403
|
+
const items = p === panel ? allItems : p.getItems(metrics);
|
|
79526
80404
|
return { total: items.length };
|
|
79527
80405
|
});
|
|
80406
|
+
const handleMouse = useMouseHandler({
|
|
80407
|
+
state,
|
|
80408
|
+
dispatch,
|
|
80409
|
+
panels,
|
|
80410
|
+
panelCounts,
|
|
80411
|
+
currentItems,
|
|
80412
|
+
clampedSelection,
|
|
80413
|
+
sideWidth,
|
|
80414
|
+
sideScroll,
|
|
80415
|
+
detailLines,
|
|
80416
|
+
detailViewportHeight,
|
|
80417
|
+
detailTabs,
|
|
80418
|
+
rows,
|
|
80419
|
+
rotatePhrase
|
|
80420
|
+
});
|
|
80421
|
+
useKeyboardHandler({
|
|
80422
|
+
state,
|
|
80423
|
+
dispatch,
|
|
80424
|
+
panels,
|
|
80425
|
+
panel,
|
|
80426
|
+
selectedItem,
|
|
80427
|
+
contextActions,
|
|
80428
|
+
clampedSelection,
|
|
80429
|
+
currentItems,
|
|
80430
|
+
detailLines,
|
|
80431
|
+
detailViewportHeight,
|
|
80432
|
+
detailTabs,
|
|
80433
|
+
tabIdx,
|
|
80434
|
+
panelActions,
|
|
80435
|
+
sideScroll,
|
|
80436
|
+
addToast,
|
|
80437
|
+
rotatePhrase
|
|
80438
|
+
});
|
|
80439
|
+
if (tooSmall) {
|
|
80440
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TooSmallOverlay, { columns, rows });
|
|
80441
|
+
}
|
|
79528
80442
|
const showNormalLayout = state.overlay !== "help" && state.overlay !== "exec" && state.overlay !== "version";
|
|
79529
|
-
const
|
|
79530
|
-
|
|
79531
|
-
|
|
79532
|
-
|
|
79533
|
-
|
|
79534
|
-
showNormalLayout && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Box_default, { flexGrow: 1, flexDirection: "row", children: [
|
|
79535
|
-
sideWidth > 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
80443
|
+
const panelActionHints = applicableActions.map((a) => ({ key: a.key, label: a.label, destructive: !!a.confirm }));
|
|
80444
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(MouseProvider, { onMouse: handleMouse, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Box_default, { flexDirection: "column", height: rows, width: columns, children: [
|
|
80445
|
+
showNormalLayout && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TabBar, { panels, activeIndex: state.activePanelIndex, layoutMode: state.layoutMode, phrase, panelCounts }),
|
|
80446
|
+
showNormalLayout && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Box_default, { flexGrow: 1, flexDirection: "row", children: [
|
|
80447
|
+
sideWidth > 0 && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
79536
80448
|
SideList,
|
|
79537
80449
|
{
|
|
79538
80450
|
items: currentItems,
|
|
@@ -79548,9 +80460,9 @@ function Dashboard({ panels, metrics, onSelectionChange, execTriggerRef, onExecF
|
|
|
79548
80460
|
runningCount: panel.id === "containers" ? runningCount : void 0
|
|
79549
80461
|
}
|
|
79550
80462
|
),
|
|
79551
|
-
/* @__PURE__ */ (0,
|
|
79552
|
-
/* @__PURE__ */ (0,
|
|
79553
|
-
/* @__PURE__ */ (0,
|
|
80463
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Box_default, { flexDirection: "column", flexGrow: 1, children: [
|
|
80464
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(DetailTabBar, { tabs: detailTabs, activeIndex: state.detailTabIndex }),
|
|
80465
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
79554
80466
|
DetailPane,
|
|
79555
80467
|
{
|
|
79556
80468
|
content: detailContent,
|
|
@@ -79561,33 +80473,32 @@ function Dashboard({ panels, metrics, onSelectionChange, execTriggerRef, onExecF
|
|
|
79561
80473
|
)
|
|
79562
80474
|
] })
|
|
79563
80475
|
] }),
|
|
79564
|
-
state.overlay === "help" && /* @__PURE__ */ (0,
|
|
79565
|
-
state.overlay === "version" && /* @__PURE__ */ (0,
|
|
79566
|
-
state.overlay === "exec" && /* @__PURE__ */ (0,
|
|
80476
|
+
state.overlay === "help" && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(HelpOverlay, { panels, activePanelIndex: state.activePanelIndex, version: "0.1.3" }),
|
|
80477
|
+
state.overlay === "version" && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(VersionOverlay, { version: "0.1.3" }),
|
|
80478
|
+
state.overlay === "exec" && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
79567
80479
|
ExecOverlay,
|
|
79568
80480
|
{
|
|
79569
80481
|
containerName: state.execContainerName,
|
|
79570
80482
|
outputLines: state.execOutputLines
|
|
79571
80483
|
}
|
|
79572
80484
|
),
|
|
79573
|
-
state.overlay !== "exec" && /* @__PURE__ */ (0,
|
|
80485
|
+
state.overlay !== "exec" && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
79574
80486
|
StatusBar,
|
|
79575
80487
|
{
|
|
79576
80488
|
daemonConnected: metrics.daemonConnected,
|
|
79577
80489
|
focusTarget: state.focusTarget,
|
|
79578
|
-
panelHints: "",
|
|
79579
80490
|
panelActionHints,
|
|
79580
80491
|
filterString: state.filterString,
|
|
79581
80492
|
containerCount: metrics.containers.length,
|
|
79582
80493
|
runningCount,
|
|
79583
|
-
version: "0.1.
|
|
80494
|
+
version: "0.1.3",
|
|
79584
80495
|
matchCount: state.filterString ? currentItems.length : void 0,
|
|
79585
80496
|
totalCount: state.filterString ? totalItemCount : void 0,
|
|
79586
80497
|
lastRefresh: metrics.lastRefresh
|
|
79587
80498
|
}
|
|
79588
80499
|
),
|
|
79589
|
-
state.overlay === "context-menu" && /* @__PURE__ */ (0,
|
|
79590
|
-
state.overlay === "filter" && /* @__PURE__ */ (0,
|
|
80500
|
+
state.overlay === "context-menu" && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ContextMenuOverlay, { actions: contextActions, selectedIndex: state.contextMenuIndex }),
|
|
80501
|
+
state.overlay === "filter" && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
79591
80502
|
FilterOverlay,
|
|
79592
80503
|
{
|
|
79593
80504
|
filterString: state.filterString,
|
|
@@ -79596,7 +80507,14 @@ function Dashboard({ panels, metrics, onSelectionChange, execTriggerRef, onExecF
|
|
|
79596
80507
|
panelTitle: panel.title
|
|
79597
80508
|
}
|
|
79598
80509
|
),
|
|
79599
|
-
state.overlay === "
|
|
80510
|
+
state.overlay === "log-filter" && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
80511
|
+
LogFilterOverlay,
|
|
80512
|
+
{
|
|
80513
|
+
filterString: state.logFilterString,
|
|
80514
|
+
filterMode: state.logFilterMode
|
|
80515
|
+
}
|
|
80516
|
+
),
|
|
80517
|
+
state.overlay === "confirm" && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
79600
80518
|
ConfirmOverlay,
|
|
79601
80519
|
{
|
|
79602
80520
|
message: state.confirmMessage,
|
|
@@ -79607,7 +80525,7 @@ function Dashboard({ panels, metrics, onSelectionChange, execTriggerRef, onExecF
|
|
|
79607
80525
|
onCancel: () => dispatch({ type: "SET_CONFIRM", action: null, message: "" })
|
|
79608
80526
|
}
|
|
79609
80527
|
),
|
|
79610
|
-
state.toasts.length > 0 && /* @__PURE__ */ (0,
|
|
80528
|
+
state.toasts.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ToastNotification, { toast: state.toasts[state.toasts.length - 1] })
|
|
79611
80529
|
] }) });
|
|
79612
80530
|
}
|
|
79613
80531
|
|
|
@@ -79615,7 +80533,7 @@ function Dashboard({ panels, metrics, onSelectionChange, execTriggerRef, onExecF
|
|
|
79615
80533
|
async function dashboardAction(_opts, cmd) {
|
|
79616
80534
|
const globalOpts = cmd.parent?.opts() ?? cmd.opts();
|
|
79617
80535
|
const socketPath = globalOpts.socket;
|
|
79618
|
-
const client = new
|
|
80536
|
+
const client = new import_sidekick_docker_shared13.DockerClient(socketPath ? { socketPath } : void 0);
|
|
79619
80537
|
const ok = await client.ping();
|
|
79620
80538
|
if (!ok) {
|
|
79621
80539
|
console.error("Error: Cannot connect to Docker daemon. Is Docker running?");
|
|
@@ -79624,15 +80542,19 @@ async function dashboardAction(_opts, cmd) {
|
|
|
79624
80542
|
const cwd2 = process.cwd();
|
|
79625
80543
|
const state = new DockerState(client, cwd2);
|
|
79626
80544
|
await state.refresh();
|
|
79627
|
-
const composeClient = new
|
|
80545
|
+
const composeClient = new import_sidekick_docker_shared13.ComposeClient();
|
|
79628
80546
|
const onAction = () => {
|
|
79629
|
-
state.refresh().then(() => scheduleRender()).catch(() =>
|
|
79630
|
-
|
|
80547
|
+
state.refresh().then(() => scheduleRender()).catch((e) => console.debug("refresh failed:", e));
|
|
80548
|
+
};
|
|
80549
|
+
const onError = (msg) => {
|
|
80550
|
+
console.debug("panel action failed:", msg);
|
|
79631
80551
|
};
|
|
79632
80552
|
const logManager = new LogStreamManager(client, () => {
|
|
79633
80553
|
state.setSelectedLogs(logManager.getLogs());
|
|
80554
|
+
logSeverityCounts = logManager.getSeverityCounts();
|
|
79634
80555
|
scheduleRender();
|
|
79635
80556
|
});
|
|
80557
|
+
let logSeverityCounts = logManager.getSeverityCounts();
|
|
79636
80558
|
const statsManager = new StatsStreamManager(client, state.getStatsCollector(), () => {
|
|
79637
80559
|
scheduleRender();
|
|
79638
80560
|
});
|
|
@@ -79652,8 +80574,7 @@ async function dashboardAction(_opts, cmd) {
|
|
|
79652
80574
|
client.inspectContainer(itemId).then((info) => {
|
|
79653
80575
|
state.setInspectedEnv(itemId, info.Config.Env || []);
|
|
79654
80576
|
scheduleRender();
|
|
79655
|
-
}).catch(() =>
|
|
79656
|
-
});
|
|
80577
|
+
}).catch((e) => console.debug("inspectContainer failed:", e));
|
|
79657
80578
|
}
|
|
79658
80579
|
} else if (panelId === "services" && itemId) {
|
|
79659
80580
|
logManager.select(null);
|
|
@@ -79671,24 +80592,24 @@ async function dashboardAction(_opts, cmd) {
|
|
|
79671
80592
|
}
|
|
79672
80593
|
};
|
|
79673
80594
|
const panels = [
|
|
79674
|
-
new ContainersPanel(client, onAction),
|
|
79675
|
-
new ServicesPanel(composeClient, onAction, cwd2),
|
|
79676
|
-
new ImagesPanel(client, onAction),
|
|
79677
|
-
new VolumesPanel(client, onAction),
|
|
79678
|
-
new NetworksPanel(client, onAction)
|
|
80595
|
+
new ContainersPanel(client, onAction, onError),
|
|
80596
|
+
new ServicesPanel(composeClient, onAction, cwd2, onError),
|
|
80597
|
+
new ImagesPanel(client, onAction, onError),
|
|
80598
|
+
new VolumesPanel(client, onAction, onError),
|
|
80599
|
+
new NetworksPanel(client, onAction, onError)
|
|
79679
80600
|
];
|
|
79680
|
-
const watcher = new
|
|
80601
|
+
const watcher = new import_sidekick_docker_shared13.EventWatcher(client, {
|
|
79681
80602
|
onEvent: (event) => {
|
|
79682
80603
|
state.processEvent(event);
|
|
79683
80604
|
scheduleRender();
|
|
79684
80605
|
},
|
|
79685
|
-
onError: () => {
|
|
80606
|
+
onError: (err) => {
|
|
80607
|
+
console.debug("event watcher error:", err.message);
|
|
79686
80608
|
}
|
|
79687
80609
|
});
|
|
79688
80610
|
watcher.start();
|
|
79689
80611
|
const refreshInterval = setInterval(() => {
|
|
79690
|
-
state.refresh().then(() => scheduleRender()).catch(() =>
|
|
79691
|
-
});
|
|
80612
|
+
state.refresh().then(() => scheduleRender()).catch((e) => console.debug("periodic refresh failed:", e));
|
|
79692
80613
|
}, 3e4);
|
|
79693
80614
|
const execTriggerRef = { current: null };
|
|
79694
80615
|
const onExecFallback = (containerId) => {
|
|
@@ -79699,9 +80620,9 @@ async function dashboardAction(_opts, cmd) {
|
|
|
79699
80620
|
stdio: "inherit"
|
|
79700
80621
|
});
|
|
79701
80622
|
instance = render2(
|
|
79702
|
-
|
|
80623
|
+
import_react37.default.createElement(Dashboard, {
|
|
79703
80624
|
panels,
|
|
79704
|
-
metrics:
|
|
80625
|
+
metrics: getEnrichedMetrics(),
|
|
79705
80626
|
onSelectionChange,
|
|
79706
80627
|
execTriggerRef,
|
|
79707
80628
|
onExecFallback
|
|
@@ -79711,9 +80632,9 @@ async function dashboardAction(_opts, cmd) {
|
|
|
79711
80632
|
};
|
|
79712
80633
|
const { render: render2 } = await init_build2().then(() => build_exports);
|
|
79713
80634
|
let instance = render2(
|
|
79714
|
-
|
|
80635
|
+
import_react37.default.createElement(Dashboard, {
|
|
79715
80636
|
panels,
|
|
79716
|
-
metrics:
|
|
80637
|
+
metrics: getEnrichedMetrics(),
|
|
79717
80638
|
onSelectionChange,
|
|
79718
80639
|
execTriggerRef,
|
|
79719
80640
|
onExecFallback
|
|
@@ -79730,14 +80651,21 @@ async function dashboardAction(_opts, cmd) {
|
|
|
79730
80651
|
}
|
|
79731
80652
|
});
|
|
79732
80653
|
let renderTimer = null;
|
|
80654
|
+
function getEnrichedMetrics() {
|
|
80655
|
+
const m = state.getMetrics();
|
|
80656
|
+
m.logSeverityCounts = logSeverityCounts;
|
|
80657
|
+
m.logSeverityTimeSeries = logManager.getSeverityTimeSeries();
|
|
80658
|
+
m.logTemplates = logManager.getTemplates();
|
|
80659
|
+
return m;
|
|
80660
|
+
}
|
|
79733
80661
|
function scheduleRender() {
|
|
79734
80662
|
if (renderTimer) return;
|
|
79735
80663
|
renderTimer = setTimeout(() => {
|
|
79736
80664
|
renderTimer = null;
|
|
79737
80665
|
instance.rerender(
|
|
79738
|
-
|
|
80666
|
+
import_react37.default.createElement(Dashboard, {
|
|
79739
80667
|
panels,
|
|
79740
|
-
metrics:
|
|
80668
|
+
metrics: getEnrichedMetrics(),
|
|
79741
80669
|
onSelectionChange,
|
|
79742
80670
|
execTriggerRef,
|
|
79743
80671
|
onExecFallback
|
|
@@ -79785,9 +80713,9 @@ async function dashboardAction(_opts, cmd) {
|
|
|
79785
80713
|
}
|
|
79786
80714
|
|
|
79787
80715
|
// src/commands/ps.ts
|
|
79788
|
-
var
|
|
80716
|
+
var import_sidekick_docker_shared14 = __toESM(require_dist(), 1);
|
|
79789
80717
|
async function psAction(opts) {
|
|
79790
|
-
const client = new
|
|
80718
|
+
const client = new import_sidekick_docker_shared14.DockerClient();
|
|
79791
80719
|
const ok = await client.ping();
|
|
79792
80720
|
if (!ok) {
|
|
79793
80721
|
console.error("Error: Cannot connect to Docker daemon. Is Docker running?");
|
|
@@ -79804,19 +80732,19 @@ async function psAction(opts) {
|
|
|
79804
80732
|
for (const c of containers) {
|
|
79805
80733
|
const row = [
|
|
79806
80734
|
c.id.substring(0, 12).padEnd(20),
|
|
79807
|
-
`${(0,
|
|
80735
|
+
`${(0, import_sidekick_docker_shared3.stateIcon)(c.state)} ${c.name}`.padEnd(20),
|
|
79808
80736
|
c.image.padEnd(20),
|
|
79809
80737
|
formatUptime(c.status).padEnd(20),
|
|
79810
|
-
(0,
|
|
80738
|
+
(0, import_sidekick_docker_shared3.formatPorts)(c.ports)
|
|
79811
80739
|
].join("");
|
|
79812
80740
|
console.log(row);
|
|
79813
80741
|
}
|
|
79814
80742
|
}
|
|
79815
80743
|
|
|
79816
80744
|
// src/commands/logs.ts
|
|
79817
|
-
var
|
|
80745
|
+
var import_sidekick_docker_shared15 = __toESM(require_dist(), 1);
|
|
79818
80746
|
async function logsAction(container, opts) {
|
|
79819
|
-
const client = new
|
|
80747
|
+
const client = new import_sidekick_docker_shared15.DockerClient();
|
|
79820
80748
|
const ok = await client.ping();
|
|
79821
80749
|
if (!ok) {
|
|
79822
80750
|
console.error("Error: Cannot connect to Docker daemon. Is Docker running?");
|
|
@@ -79833,7 +80761,7 @@ async function logsAction(container, opts) {
|
|
|
79833
80761
|
console.log(`${prefix}${ts} ${entry.message}${reset}`);
|
|
79834
80762
|
}
|
|
79835
80763
|
} catch (err) {
|
|
79836
|
-
const msg =
|
|
80764
|
+
const msg = (0, import_sidekick_docker_shared15.errorMessage)(err);
|
|
79837
80765
|
if (msg.includes("no such container") || msg.includes("No such container")) {
|
|
79838
80766
|
console.error(`Error: Container "${container}" not found.`);
|
|
79839
80767
|
} else {
|
|
@@ -79845,7 +80773,7 @@ async function logsAction(container, opts) {
|
|
|
79845
80773
|
|
|
79846
80774
|
// src/cli.ts
|
|
79847
80775
|
var program2 = new Command();
|
|
79848
|
-
program2.name("sidekick-docker").description("Docker management TUI dashboard").version("0.1.
|
|
80776
|
+
program2.name("sidekick-docker").description("Docker management TUI dashboard").version("0.1.3").option("--socket <path>", "Docker socket path").action(async (_opts, cmd) => {
|
|
79849
80777
|
await dashboardAction(_opts, cmd);
|
|
79850
80778
|
});
|
|
79851
80779
|
program2.command("ps").description("List containers").option("-a, --all", "Show all containers (default: running only)", false).action(async (opts) => {
|