@qodalis/cli 2.0.0-beta.16 → 2.0.0-beta.17
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/assets/cli-panel.css +12 -0
- package/package.json +2 -2
- package/public-api.d.mts +61 -8
- package/public-api.d.ts +61 -8
- package/public-api.js +423 -214
- package/public-api.js.map +1 -1
- package/public-api.mjs +422 -215
- package/public-api.mjs.map +1 -1
package/public-api.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var cliCore = require('@qodalis/cli-core');
|
|
4
|
-
var rxjs = require('rxjs');
|
|
5
|
-
var operators = require('rxjs/operators');
|
|
6
4
|
var xterm = require('@xterm/xterm');
|
|
7
5
|
var addonFit = require('@xterm/addon-fit');
|
|
8
6
|
var addonWebLinks = require('@xterm/addon-web-links');
|
|
9
7
|
var addonUnicode11 = require('@xterm/addon-unicode11');
|
|
10
8
|
var addonSerialize = require('@xterm/addon-serialize');
|
|
9
|
+
var rxjs = require('rxjs');
|
|
10
|
+
var operators = require('rxjs/operators');
|
|
11
11
|
|
|
12
12
|
// src/lib/parsers/command-parser.ts
|
|
13
13
|
var CommandParser = class {
|
|
@@ -413,7 +413,7 @@ var CliKeyValueStore_TOKEN = "cli-key-value-store";
|
|
|
413
413
|
var SyntaxHighlighterRegistry_TOKEN = "syntax-highlighter-registry";
|
|
414
414
|
|
|
415
415
|
// src/lib/version.ts
|
|
416
|
-
var LIBRARY_VERSION = "2.0.0-beta.
|
|
416
|
+
var LIBRARY_VERSION = "2.0.0-beta.17";
|
|
417
417
|
var API_VERSION = 2;
|
|
418
418
|
var ANONYMOUS = "\0anonymous";
|
|
419
419
|
function aliasOwner(context2) {
|
|
@@ -2699,6 +2699,150 @@ var CliYesCommandProcessor = class {
|
|
|
2699
2699
|
);
|
|
2700
2700
|
}
|
|
2701
2701
|
};
|
|
2702
|
+
|
|
2703
|
+
// src/lib/addons/overlay.ts
|
|
2704
|
+
var OverlayAddon = class {
|
|
2705
|
+
constructor() {
|
|
2706
|
+
this.overlayNode = document.createElement("div");
|
|
2707
|
+
this.overlayNode.style.cssText = `border-radius: 15px;
|
|
2708
|
+
font-size: xx-large;
|
|
2709
|
+
opacity: 0.75;
|
|
2710
|
+
padding: 0.2em 0.5em 0.2em 0.5em;
|
|
2711
|
+
position: absolute;
|
|
2712
|
+
-webkit-user-select: none;
|
|
2713
|
+
-webkit-transition: opacity 180ms ease-in;
|
|
2714
|
+
-moz-user-select: none;
|
|
2715
|
+
-moz-transition: opacity 180ms ease-in;`;
|
|
2716
|
+
this.overlayNode.addEventListener(
|
|
2717
|
+
"mousedown",
|
|
2718
|
+
(e) => {
|
|
2719
|
+
e.preventDefault();
|
|
2720
|
+
e.stopPropagation();
|
|
2721
|
+
},
|
|
2722
|
+
true
|
|
2723
|
+
);
|
|
2724
|
+
}
|
|
2725
|
+
activate(terminal) {
|
|
2726
|
+
this.terminal = terminal;
|
|
2727
|
+
}
|
|
2728
|
+
dispose() {
|
|
2729
|
+
}
|
|
2730
|
+
showOverlay(msg, timeout) {
|
|
2731
|
+
const { terminal, overlayNode } = this;
|
|
2732
|
+
if (!terminal.element) return;
|
|
2733
|
+
overlayNode.style.color = "#101010";
|
|
2734
|
+
overlayNode.style.backgroundColor = "#f0f0f0";
|
|
2735
|
+
overlayNode.textContent = msg;
|
|
2736
|
+
overlayNode.style.opacity = "0.75";
|
|
2737
|
+
if (!overlayNode.parentNode) {
|
|
2738
|
+
terminal.element.appendChild(overlayNode);
|
|
2739
|
+
}
|
|
2740
|
+
const divSize = terminal.element.getBoundingClientRect();
|
|
2741
|
+
const overlaySize = overlayNode.getBoundingClientRect();
|
|
2742
|
+
overlayNode.style.top = (divSize.height - overlaySize.height) / 2 + "px";
|
|
2743
|
+
overlayNode.style.left = (divSize.width - overlaySize.width) / 2 + "px";
|
|
2744
|
+
if (this.overlayTimeout) clearTimeout(this.overlayTimeout);
|
|
2745
|
+
if (!timeout) return;
|
|
2746
|
+
this.overlayTimeout = window.setTimeout(() => {
|
|
2747
|
+
overlayNode.style.opacity = "0";
|
|
2748
|
+
this.overlayTimeout = window.setTimeout(() => {
|
|
2749
|
+
if (overlayNode.parentNode) {
|
|
2750
|
+
overlayNode.parentNode.removeChild(overlayNode);
|
|
2751
|
+
}
|
|
2752
|
+
this.overlayTimeout = void 0;
|
|
2753
|
+
overlayNode.style.opacity = "0.75";
|
|
2754
|
+
}, 200);
|
|
2755
|
+
}, timeout || 1500);
|
|
2756
|
+
}
|
|
2757
|
+
};
|
|
2758
|
+
var CliDragDropService = class {
|
|
2759
|
+
constructor(_container) {
|
|
2760
|
+
this._container = _container;
|
|
2761
|
+
this._subject = new rxjs.Subject();
|
|
2762
|
+
this._dragOver = (e) => e.preventDefault();
|
|
2763
|
+
this._drop = (e) => {
|
|
2764
|
+
e.preventDefault();
|
|
2765
|
+
const files = Array.from(e.dataTransfer?.files ?? []);
|
|
2766
|
+
if (files.length > 0) {
|
|
2767
|
+
this._subject.next(files);
|
|
2768
|
+
}
|
|
2769
|
+
};
|
|
2770
|
+
this._container.addEventListener("dragover", this._dragOver);
|
|
2771
|
+
this._container.addEventListener("drop", this._drop);
|
|
2772
|
+
}
|
|
2773
|
+
get onFileDrop() {
|
|
2774
|
+
return this._subject.asObservable();
|
|
2775
|
+
}
|
|
2776
|
+
destroy() {
|
|
2777
|
+
this._container.removeEventListener("dragover", this._dragOver);
|
|
2778
|
+
this._container.removeEventListener("drop", this._drop);
|
|
2779
|
+
this._subject.complete();
|
|
2780
|
+
}
|
|
2781
|
+
};
|
|
2782
|
+
|
|
2783
|
+
// src/lib/engine/cli-terminal-setup.ts
|
|
2784
|
+
var NARROW_VIEWPORT = 640;
|
|
2785
|
+
function defaultFontSize() {
|
|
2786
|
+
const width = typeof window !== "undefined" ? window.innerWidth : 0;
|
|
2787
|
+
return width > 0 && width <= NARROW_VIEWPORT ? 14 : 20;
|
|
2788
|
+
}
|
|
2789
|
+
function getTerminalOptions(userOptions) {
|
|
2790
|
+
return {
|
|
2791
|
+
cursorBlink: true,
|
|
2792
|
+
allowProposedApi: true,
|
|
2793
|
+
fontSize: defaultFontSize(),
|
|
2794
|
+
theme: cliCore.DefaultThemes.default,
|
|
2795
|
+
convertEol: true,
|
|
2796
|
+
...userOptions ?? {}
|
|
2797
|
+
};
|
|
2798
|
+
}
|
|
2799
|
+
function initializeTerminal(container, opts) {
|
|
2800
|
+
const terminal = new xterm.Terminal(opts);
|
|
2801
|
+
const fitAddon = new addonFit.FitAddon();
|
|
2802
|
+
terminal.loadAddon(fitAddon);
|
|
2803
|
+
terminal.loadAddon(new addonWebLinks.WebLinksAddon());
|
|
2804
|
+
terminal.loadAddon(new OverlayAddon());
|
|
2805
|
+
terminal.loadAddon(new addonUnicode11.Unicode11Addon());
|
|
2806
|
+
const serializeAddon = new addonSerialize.SerializeAddon();
|
|
2807
|
+
terminal.loadAddon(serializeAddon);
|
|
2808
|
+
terminal.open(container);
|
|
2809
|
+
fitAddon.fit();
|
|
2810
|
+
requestAnimationFrame(() => fitAddon.fit());
|
|
2811
|
+
if (document.fonts?.ready) {
|
|
2812
|
+
document.fonts.ready.then(() => {
|
|
2813
|
+
requestAnimationFrame(() => fitAddon.fit());
|
|
2814
|
+
});
|
|
2815
|
+
}
|
|
2816
|
+
container.classList.add("terminal-container");
|
|
2817
|
+
container.style.background = opts.theme?.background ?? "#000";
|
|
2818
|
+
const wheelListener = (e) => e.preventDefault();
|
|
2819
|
+
container.addEventListener("wheel", wheelListener, { passive: false });
|
|
2820
|
+
terminal.focus();
|
|
2821
|
+
const dragDropService = new CliDragDropService(container);
|
|
2822
|
+
return { terminal, fitAddon, serializeAddon, dragDropService, wheelListener };
|
|
2823
|
+
}
|
|
2824
|
+
var LAYOUT_TIMEOUT_MS = 1e4;
|
|
2825
|
+
function waitForLayout(container) {
|
|
2826
|
+
return new Promise((resolve, reject) => {
|
|
2827
|
+
const deadline = Date.now() + LAYOUT_TIMEOUT_MS;
|
|
2828
|
+
const check = () => {
|
|
2829
|
+
if (container.offsetWidth > 0 && container.offsetHeight > 0) {
|
|
2830
|
+
resolve();
|
|
2831
|
+
return;
|
|
2832
|
+
}
|
|
2833
|
+
if (Date.now() >= deadline) {
|
|
2834
|
+
reject(new Error(
|
|
2835
|
+
`CliEngine.start(): container has zero dimensions after ${LAYOUT_TIMEOUT_MS}ms. Ensure the container element is visible and laid out before calling start().`
|
|
2836
|
+
));
|
|
2837
|
+
return;
|
|
2838
|
+
}
|
|
2839
|
+
requestAnimationFrame(check);
|
|
2840
|
+
};
|
|
2841
|
+
check();
|
|
2842
|
+
});
|
|
2843
|
+
}
|
|
2844
|
+
|
|
2845
|
+
// src/lib/processors/configure/cli-configure-command-processor.ts
|
|
2702
2846
|
var SYSTEM_OPTIONS = [
|
|
2703
2847
|
{
|
|
2704
2848
|
key: "logLevel",
|
|
@@ -2775,7 +2919,7 @@ var SYSTEM_OPTIONS = [
|
|
|
2775
2919
|
label: "Font Size",
|
|
2776
2920
|
description: "Terminal font size in pixels",
|
|
2777
2921
|
type: "number",
|
|
2778
|
-
defaultValue:
|
|
2922
|
+
defaultValue: defaultFontSize(),
|
|
2779
2923
|
validator: (value) => {
|
|
2780
2924
|
if (value < 8 || value > 40) {
|
|
2781
2925
|
return { valid: false, message: "Font size must be between 8 and 40" };
|
|
@@ -2855,7 +2999,7 @@ var CliConfigureCommandProcessor = class _CliConfigureCommandProcessor {
|
|
|
2855
2999
|
async initialize(context2) {
|
|
2856
3000
|
const state = context2.state.getState();
|
|
2857
3001
|
if (state?.system) {
|
|
2858
|
-
this.applySystemSettings(state.system, context2);
|
|
3002
|
+
this.applySystemSettings(state.system, context2, true);
|
|
2859
3003
|
}
|
|
2860
3004
|
}
|
|
2861
3005
|
writeDescription(context2) {
|
|
@@ -3090,7 +3234,11 @@ var CliConfigureCommandProcessor = class _CliConfigureCommandProcessor {
|
|
|
3090
3234
|
}
|
|
3091
3235
|
return result;
|
|
3092
3236
|
}
|
|
3093
|
-
|
|
3237
|
+
/**
|
|
3238
|
+
* @param onBoot at startup, terminal options still at their default are skipped so the
|
|
3239
|
+
* host's `terminalOptions` (e.g. its own fontSize) are not overridden.
|
|
3240
|
+
*/
|
|
3241
|
+
applySystemSettings(settings, context2, onBoot = false) {
|
|
3094
3242
|
if (settings["logLevel"]) {
|
|
3095
3243
|
const level = LOG_LEVEL_MAP[settings["logLevel"]];
|
|
3096
3244
|
if (level !== void 0) {
|
|
@@ -3104,23 +3252,29 @@ var CliConfigureCommandProcessor = class _CliConfigureCommandProcessor {
|
|
|
3104
3252
|
translator?.setLocale(settings["language"]);
|
|
3105
3253
|
}
|
|
3106
3254
|
if (context2.terminal?.options) {
|
|
3107
|
-
|
|
3108
|
-
|
|
3255
|
+
const terminal = onBoot ? Object.fromEntries(
|
|
3256
|
+
Object.entries(settings).filter(([key, value]) => {
|
|
3257
|
+
const option = SYSTEM_OPTIONS.find((o) => o.key === key);
|
|
3258
|
+
return !option || value !== option.defaultValue;
|
|
3259
|
+
})
|
|
3260
|
+
) : settings;
|
|
3261
|
+
if (terminal["cursorBlink"] !== void 0) {
|
|
3262
|
+
context2.terminal.options.cursorBlink = terminal["cursorBlink"];
|
|
3109
3263
|
}
|
|
3110
|
-
if (
|
|
3111
|
-
context2.terminal.options.cursorStyle =
|
|
3264
|
+
if (terminal["cursorStyle"]) {
|
|
3265
|
+
context2.terminal.options.cursorStyle = terminal["cursorStyle"];
|
|
3112
3266
|
}
|
|
3113
|
-
if (
|
|
3114
|
-
context2.terminal.options.scrollback =
|
|
3267
|
+
if (terminal["scrollback"] !== void 0) {
|
|
3268
|
+
context2.terminal.options.scrollback = terminal["scrollback"];
|
|
3115
3269
|
}
|
|
3116
|
-
if (
|
|
3117
|
-
context2.terminal.options.fontSize =
|
|
3270
|
+
if (terminal["fontSize"] !== void 0) {
|
|
3271
|
+
context2.terminal.options.fontSize = terminal["fontSize"];
|
|
3118
3272
|
}
|
|
3119
|
-
if (
|
|
3120
|
-
context2.terminal.options.fontFamily =
|
|
3273
|
+
if (terminal["fontFamily"]) {
|
|
3274
|
+
context2.terminal.options.fontFamily = terminal["fontFamily"];
|
|
3121
3275
|
}
|
|
3122
|
-
if (
|
|
3123
|
-
context2.terminal.options.smoothScrollDuration =
|
|
3276
|
+
if (terminal["smoothScrollDuration"] !== void 0) {
|
|
3277
|
+
context2.terminal.options.smoothScrollDuration = terminal["smoothScrollDuration"];
|
|
3124
3278
|
}
|
|
3125
3279
|
}
|
|
3126
3280
|
}
|
|
@@ -3718,6 +3872,7 @@ var CliHelpCommandProcessor = class {
|
|
|
3718
3872
|
return 0;
|
|
3719
3873
|
}
|
|
3720
3874
|
);
|
|
3875
|
+
const narrow = isNarrow(context2);
|
|
3721
3876
|
sortedModules.forEach(([module, processors]) => {
|
|
3722
3877
|
const displayName = this.formatModuleName(module);
|
|
3723
3878
|
writer.writeln(
|
|
@@ -3726,7 +3881,7 @@ var CliHelpCommandProcessor = class {
|
|
|
3726
3881
|
processors.forEach((processor) => {
|
|
3727
3882
|
const icon = processor?.metadata?.icon || cliCore.CliIcon.Extension;
|
|
3728
3883
|
const name = writer.wrapInColor(
|
|
3729
|
-
processor.command.padEnd(20),
|
|
3884
|
+
narrow ? processor.command : processor.command.padEnd(20),
|
|
3730
3885
|
cliCore.CliForegroundColor.Cyan
|
|
3731
3886
|
);
|
|
3732
3887
|
const aliasText = processor.aliases?.length ? `${DIM} ${processor.aliases.join(", ")}${RESET}` : "";
|
|
@@ -3735,6 +3890,11 @@ var CliHelpCommandProcessor = class {
|
|
|
3735
3890
|
processor.command,
|
|
3736
3891
|
context2
|
|
3737
3892
|
);
|
|
3893
|
+
if (narrow) {
|
|
3894
|
+
writer.writeln(` ${icon} ${name}${aliasText}`);
|
|
3895
|
+
writer.writeln(` ${desc}`);
|
|
3896
|
+
return;
|
|
3897
|
+
}
|
|
3738
3898
|
writer.writeln(` ${icon} ${name} ${desc}${aliasText}`);
|
|
3739
3899
|
});
|
|
3740
3900
|
writer.writeln();
|
|
@@ -3844,9 +4004,10 @@ var CliHelpCommandProcessor = class {
|
|
|
3844
4004
|
writer.writeln(
|
|
3845
4005
|
` ${BOLD}${writer.wrapInColor(t.t("cli.help.subcommands", "Subcommands"), cliCore.CliForegroundColor.Yellow)}${RESET}`
|
|
3846
4006
|
);
|
|
4007
|
+
const narrow = isNarrow(context2);
|
|
3847
4008
|
processor.processors.forEach((sub) => {
|
|
3848
4009
|
const subName = writer.wrapInColor(
|
|
3849
|
-
sub.command.padEnd(16),
|
|
4010
|
+
narrow ? sub.command : sub.command.padEnd(16),
|
|
3850
4011
|
cliCore.CliForegroundColor.Cyan
|
|
3851
4012
|
);
|
|
3852
4013
|
const subAliases = sub.aliases?.length ? `${DIM} (${sub.aliases.join(", ")})${RESET}` : "";
|
|
@@ -3855,6 +4016,11 @@ var CliHelpCommandProcessor = class {
|
|
|
3855
4016
|
`${processor.command}.${sub.command}`,
|
|
3856
4017
|
context2
|
|
3857
4018
|
);
|
|
4019
|
+
if (narrow) {
|
|
4020
|
+
writer.writeln(` ${subName}${subAliases}`);
|
|
4021
|
+
writer.writeln(` ${subDesc}`);
|
|
4022
|
+
return;
|
|
4023
|
+
}
|
|
3858
4024
|
writer.writeln(
|
|
3859
4025
|
` ${subName} ${subDesc}${subAliases}`
|
|
3860
4026
|
);
|
|
@@ -3868,7 +4034,7 @@ var CliHelpCommandProcessor = class {
|
|
|
3868
4034
|
` ${BOLD}${writer.wrapInColor(t.t("cli.help.options", "Options"), cliCore.CliForegroundColor.Yellow)}${RESET}`
|
|
3869
4035
|
);
|
|
3870
4036
|
commandParams.forEach((param) => {
|
|
3871
|
-
this.writeParameter(param, writer, t);
|
|
4037
|
+
this.writeParameter(param, writer, t, isNarrow(context2));
|
|
3872
4038
|
});
|
|
3873
4039
|
}
|
|
3874
4040
|
if (globalParams.length > 0) {
|
|
@@ -3877,7 +4043,7 @@ var CliHelpCommandProcessor = class {
|
|
|
3877
4043
|
` ${BOLD}${writer.wrapInColor(t.t("cli.help.global_options", "Global options"), cliCore.CliForegroundColor.Yellow)}${RESET}`
|
|
3878
4044
|
);
|
|
3879
4045
|
globalParams.forEach((param) => {
|
|
3880
|
-
this.writeParameter(param, writer, t);
|
|
4046
|
+
this.writeParameter(param, writer, t, isNarrow(context2));
|
|
3881
4047
|
});
|
|
3882
4048
|
}
|
|
3883
4049
|
if (processor.metadata?.requireServer) {
|
|
@@ -3899,7 +4065,7 @@ var CliHelpCommandProcessor = class {
|
|
|
3899
4065
|
}
|
|
3900
4066
|
return module.charAt(0).toUpperCase() + module.slice(1);
|
|
3901
4067
|
}
|
|
3902
|
-
writeParameter(param, writer, translator) {
|
|
4068
|
+
writeParameter(param, writer, translator, narrow = false) {
|
|
3903
4069
|
const aliases = param.aliases?.length ? `, ${param.aliases.map((a) => `-${a}`).join(", ")}` : "";
|
|
3904
4070
|
const nameStr = writer.wrapInColor(
|
|
3905
4071
|
`--${param.name}${aliases}`,
|
|
@@ -3908,11 +4074,19 @@ var CliHelpCommandProcessor = class {
|
|
|
3908
4074
|
const typeStr = `${DIM}<${param.type}>${RESET}`;
|
|
3909
4075
|
const required = param.required ? writer.wrapInColor(` ${translator.t("cli.help.required", "(required)")}`, cliCore.CliForegroundColor.Red) : "";
|
|
3910
4076
|
const defaultVal = param.defaultValue !== void 0 && !param.required ? `${DIM} [${param.defaultValue}]${RESET}` : "";
|
|
4077
|
+
if (narrow) {
|
|
4078
|
+
writer.writeln(` ${nameStr} ${typeStr}${required}${defaultVal}`);
|
|
4079
|
+
writer.writeln(` ${param.description}`);
|
|
4080
|
+
return;
|
|
4081
|
+
}
|
|
3911
4082
|
writer.writeln(
|
|
3912
4083
|
` ${nameStr} ${typeStr} ${param.description}${required}${defaultVal}`
|
|
3913
4084
|
);
|
|
3914
4085
|
}
|
|
3915
4086
|
};
|
|
4087
|
+
function isNarrow(context2) {
|
|
4088
|
+
return (context2.terminal?.cols ?? 80) < 60;
|
|
4089
|
+
}
|
|
3916
4090
|
|
|
3917
4091
|
// src/lib/constants/index.ts
|
|
3918
4092
|
var CLi_Name_Art_Full = `
|
|
@@ -9832,11 +10006,12 @@ function hexToRgb(hex) {
|
|
|
9832
10006
|
const n = parseInt(m[1], 16);
|
|
9833
10007
|
return { r: n >> 16 & 255, g: n >> 8 & 255, b: n & 255 };
|
|
9834
10008
|
}
|
|
9835
|
-
function colorSwatch(hex) {
|
|
9836
|
-
|
|
10009
|
+
function colorSwatch(hex, width = 2) {
|
|
10010
|
+
const cell = " ".repeat(width);
|
|
10011
|
+
if (!hex) return cell;
|
|
9837
10012
|
const rgb = hexToRgb(hex);
|
|
9838
|
-
if (!rgb) return
|
|
9839
|
-
return `\x1B[48;2;${rgb.r};${rgb.g};${rgb.b}m
|
|
10013
|
+
if (!rgb) return cell;
|
|
10014
|
+
return `\x1B[48;2;${rgb.r};${rgb.g};${rgb.b}m${cell}\x1B[0m`;
|
|
9840
10015
|
}
|
|
9841
10016
|
function colorText(text, hex) {
|
|
9842
10017
|
if (!hex) return text;
|
|
@@ -9903,11 +10078,20 @@ var CliThemeCommandProcessor = class {
|
|
|
9903
10078
|
)
|
|
9904
10079
|
);
|
|
9905
10080
|
context2.writer.writeln();
|
|
10081
|
+
const narrow = (context2.terminal?.cols ?? 80) < 60;
|
|
9906
10082
|
for (const [name, info] of entries) {
|
|
9907
10083
|
const active = name === currentName ? " (active)" : "";
|
|
9908
10084
|
const swatches = PALETTE_KEYS.map(
|
|
9909
10085
|
(k) => colorSwatch(info.theme[k])
|
|
9910
10086
|
).join("");
|
|
10087
|
+
if (narrow) {
|
|
10088
|
+
const compact = PALETTE_KEYS.slice(0, 8).map((k) => colorSwatch(info.theme[k], 1)).join("");
|
|
10089
|
+
context2.writer.writeln(
|
|
10090
|
+
` ${compact} ${context2.writer.wrapInColor(name, cliCore.CliForegroundColor.Cyan)}${active}`
|
|
10091
|
+
);
|
|
10092
|
+
context2.writer.writeln(` ${info.description}`);
|
|
10093
|
+
continue;
|
|
10094
|
+
}
|
|
9911
10095
|
const nameLabel = context2.writer.wrapInColor(
|
|
9912
10096
|
name.padEnd(22),
|
|
9913
10097
|
cliCore.CliForegroundColor.Cyan
|
|
@@ -10609,37 +10793,106 @@ var CliPingCommandProcessor = class {
|
|
|
10609
10793
|
var ICliEnvironment_TOKEN = "cli-environment";
|
|
10610
10794
|
var CliEnvironment = class {
|
|
10611
10795
|
constructor() {
|
|
10612
|
-
this.
|
|
10613
|
-
|
|
10614
|
-
this.
|
|
10615
|
-
this.
|
|
10616
|
-
this.
|
|
10617
|
-
this.
|
|
10618
|
-
this.
|
|
10619
|
-
this.
|
|
10796
|
+
this.defaults = /* @__PURE__ */ new Map();
|
|
10797
|
+
/** Variables computed on read; a user's own value wins over them. */
|
|
10798
|
+
this.bound = /* @__PURE__ */ new Map();
|
|
10799
|
+
this.profiles = /* @__PURE__ */ new Map();
|
|
10800
|
+
this.profileKey = () => "";
|
|
10801
|
+
this.defaults.set("SHELL", "/bin/sh");
|
|
10802
|
+
this.defaults.set("TERM", "xterm-256color");
|
|
10803
|
+
this.defaults.set("LANG", "en_US.UTF-8");
|
|
10804
|
+
this.defaults.set("PWD", "/");
|
|
10805
|
+
this.defaults.set("HOME", "/home/user");
|
|
10806
|
+
this.defaults.set("USER", "user");
|
|
10807
|
+
this.defaults.set("PATH", "/usr/local/bin:/usr/bin:/bin");
|
|
10808
|
+
}
|
|
10809
|
+
/** Compute a variable on every read; the seeded value is the fallback while it returns nothing. */
|
|
10810
|
+
bind(name, resolver) {
|
|
10811
|
+
this.bound.set(name, resolver);
|
|
10812
|
+
}
|
|
10813
|
+
/** Pick whose changes apply (the signed-in user's name, '' when signed out). */
|
|
10814
|
+
setProfileResolver(resolver) {
|
|
10815
|
+
this.profileKey = () => resolver() ?? "";
|
|
10816
|
+
}
|
|
10817
|
+
/** Restore saved profiles (replaces the ones in memory). */
|
|
10818
|
+
load(snapshot) {
|
|
10819
|
+
this.profiles.clear();
|
|
10820
|
+
for (const [key, profile] of Object.entries(snapshot ?? {})) {
|
|
10821
|
+
this.profiles.set(key, {
|
|
10822
|
+
vars: new Map(Object.entries(profile?.vars ?? {})),
|
|
10823
|
+
unset: new Set(profile?.unset ?? [])
|
|
10824
|
+
});
|
|
10825
|
+
}
|
|
10826
|
+
}
|
|
10827
|
+
snapshot() {
|
|
10828
|
+
const result = {};
|
|
10829
|
+
for (const [key, profile] of this.profiles) {
|
|
10830
|
+
if (!profile.vars.size && !profile.unset.size) continue;
|
|
10831
|
+
result[key] = { vars: Object.fromEntries(profile.vars), unset: [...profile.unset] };
|
|
10832
|
+
}
|
|
10833
|
+
return result;
|
|
10620
10834
|
}
|
|
10621
10835
|
get(name) {
|
|
10622
|
-
|
|
10836
|
+
const profile = this.profiles.get(this.profileKey());
|
|
10837
|
+
if (profile?.vars.has(name)) return profile.vars.get(name);
|
|
10838
|
+
if (profile?.unset.has(name)) return void 0;
|
|
10839
|
+
return this.bound.get(name)?.() || this.defaults.get(name);
|
|
10623
10840
|
}
|
|
10624
10841
|
set(name, value) {
|
|
10625
|
-
this.
|
|
10842
|
+
const profile = this.currentProfile();
|
|
10843
|
+
profile.unset.delete(name);
|
|
10844
|
+
profile.vars.set(name, value);
|
|
10845
|
+
this.onChange?.(this.snapshot());
|
|
10626
10846
|
}
|
|
10627
10847
|
unset(name) {
|
|
10628
|
-
this.
|
|
10848
|
+
const profile = this.currentProfile();
|
|
10849
|
+
profile.vars.delete(name);
|
|
10850
|
+
if (this.defaults.has(name) || this.bound.has(name)) profile.unset.add(name);
|
|
10851
|
+
this.onChange?.(this.snapshot());
|
|
10629
10852
|
}
|
|
10630
10853
|
getAll() {
|
|
10854
|
+
const profile = this.profiles.get(this.profileKey());
|
|
10855
|
+
const names = /* @__PURE__ */ new Set([...this.defaults.keys(), ...this.bound.keys(), ...profile?.vars.keys() ?? []]);
|
|
10631
10856
|
const result = {};
|
|
10632
|
-
for (const
|
|
10633
|
-
|
|
10857
|
+
for (const name of names) {
|
|
10858
|
+
const value = this.get(name);
|
|
10859
|
+
if (value !== void 0) result[name] = value;
|
|
10634
10860
|
}
|
|
10635
10861
|
return result;
|
|
10636
10862
|
}
|
|
10637
10863
|
has(name) {
|
|
10638
|
-
return this.
|
|
10864
|
+
return this.get(name) !== void 0;
|
|
10865
|
+
}
|
|
10866
|
+
currentProfile() {
|
|
10867
|
+
const key = this.profileKey();
|
|
10868
|
+
let profile = this.profiles.get(key);
|
|
10869
|
+
if (!profile) {
|
|
10870
|
+
profile = { vars: /* @__PURE__ */ new Map(), unset: /* @__PURE__ */ new Set() };
|
|
10871
|
+
this.profiles.set(key, profile);
|
|
10872
|
+
}
|
|
10873
|
+
return profile;
|
|
10639
10874
|
}
|
|
10640
10875
|
};
|
|
10641
10876
|
|
|
10642
10877
|
// src/lib/processors/cli-env-command-processor.ts
|
|
10878
|
+
var ASSIGNMENT = /([A-Za-z_][A-Za-z0-9_]*)=("[^"]*"|'[^']*'|\S*)/y;
|
|
10879
|
+
var NAME = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
10880
|
+
function parseAssignments(raw) {
|
|
10881
|
+
const result = [];
|
|
10882
|
+
for (const token of raw.match(/(?:[^\s"']+|"[^"]*"|'[^']*')+/g) ?? []) {
|
|
10883
|
+
ASSIGNMENT.lastIndex = 0;
|
|
10884
|
+
const match = ASSIGNMENT.exec(token);
|
|
10885
|
+
if (match && ASSIGNMENT.lastIndex === token.length) {
|
|
10886
|
+
const quoted = /^(["']).*\1$/.test(match[2]);
|
|
10887
|
+
result.push({ name: match[1], value: quoted ? match[2].slice(1, -1) : match[2] });
|
|
10888
|
+
} else if (NAME.test(token)) {
|
|
10889
|
+
result.push({ name: token });
|
|
10890
|
+
} else {
|
|
10891
|
+
return null;
|
|
10892
|
+
}
|
|
10893
|
+
}
|
|
10894
|
+
return result;
|
|
10895
|
+
}
|
|
10643
10896
|
var CliExportCommandProcessor = class {
|
|
10644
10897
|
constructor() {
|
|
10645
10898
|
this.command = "export";
|
|
@@ -10647,6 +10900,21 @@ var CliExportCommandProcessor = class {
|
|
|
10647
10900
|
this.author = cliCore.DefaultLibraryAuthor;
|
|
10648
10901
|
this.acceptsRawInput = true;
|
|
10649
10902
|
this.metadata = { icon: "\u{1F4E6}", module: "system" };
|
|
10903
|
+
this.stateConfiguration = {
|
|
10904
|
+
storeName: "environment",
|
|
10905
|
+
initialState: { profiles: {} }
|
|
10906
|
+
};
|
|
10907
|
+
}
|
|
10908
|
+
/** Restore saved variables and save every later change (export, unset, VAR=value). */
|
|
10909
|
+
async initialize(context2) {
|
|
10910
|
+
const env = context2.services.get(ICliEnvironment_TOKEN);
|
|
10911
|
+
if (!(env instanceof CliEnvironment)) return;
|
|
10912
|
+
const store = context2.state;
|
|
10913
|
+
env.load(store.getState()?.profiles);
|
|
10914
|
+
env.onChange = (profiles) => {
|
|
10915
|
+
store.updateState({ profiles });
|
|
10916
|
+
void store.persist();
|
|
10917
|
+
};
|
|
10650
10918
|
}
|
|
10651
10919
|
async processCommand(command2, context2) {
|
|
10652
10920
|
const env = context2.services.getRequired(
|
|
@@ -10663,20 +10931,21 @@ var CliExportCommandProcessor = class {
|
|
|
10663
10931
|
}
|
|
10664
10932
|
return;
|
|
10665
10933
|
}
|
|
10666
|
-
const
|
|
10667
|
-
if (!
|
|
10934
|
+
const assignments = parseAssignments(raw);
|
|
10935
|
+
if (!assignments?.length) {
|
|
10668
10936
|
context2.writer.writeError(
|
|
10669
10937
|
`export: invalid syntax: ${raw}`
|
|
10670
10938
|
);
|
|
10671
10939
|
context2.process.exit(1, { silent: true });
|
|
10672
10940
|
return;
|
|
10673
10941
|
}
|
|
10674
|
-
const
|
|
10675
|
-
|
|
10676
|
-
|
|
10677
|
-
|
|
10942
|
+
for (const { name, value } of assignments) {
|
|
10943
|
+
if (value !== void 0) {
|
|
10944
|
+
env.set(name, value);
|
|
10945
|
+
} else if (!env.has(name)) {
|
|
10946
|
+
env.set(name, "");
|
|
10947
|
+
}
|
|
10678
10948
|
}
|
|
10679
|
-
env.set(varName, varValue);
|
|
10680
10949
|
}
|
|
10681
10950
|
writeDescription(context2) {
|
|
10682
10951
|
const { writer, translator: t } = context2;
|
|
@@ -10692,6 +10961,13 @@ var CliExportCommandProcessor = class {
|
|
|
10692
10961
|
writer.writeln(
|
|
10693
10962
|
` ${writer.wrapInColor('export VAR="hello world"', cliCore.CliForegroundColor.Cyan)} ${t.t("cli.export.set_spaces", "Set with spaces")}`
|
|
10694
10963
|
);
|
|
10964
|
+
writer.writeln(
|
|
10965
|
+
` ${writer.wrapInColor("export A=1 B=2", cliCore.CliForegroundColor.Cyan)} ${t.t("cli.export.set_many", "Set several at once")}`
|
|
10966
|
+
);
|
|
10967
|
+
writer.writeln();
|
|
10968
|
+
writer.writeln(
|
|
10969
|
+
t.t("cli.export.saved", "Variables are saved for the signed-in user and used as $VAR or ${VAR} in commands.")
|
|
10970
|
+
);
|
|
10695
10971
|
}
|
|
10696
10972
|
};
|
|
10697
10973
|
var CliUnsetCommandProcessor = class {
|
|
@@ -10706,16 +10982,15 @@ var CliUnsetCommandProcessor = class {
|
|
|
10706
10982
|
const env = context2.services.getRequired(
|
|
10707
10983
|
ICliEnvironment_TOKEN
|
|
10708
10984
|
);
|
|
10709
|
-
const
|
|
10710
|
-
if (!
|
|
10985
|
+
const names = (command2.value || "").trim().split(/\s+/).filter(Boolean);
|
|
10986
|
+
if (!names.length) {
|
|
10711
10987
|
context2.writer.writeError("unset: missing variable name");
|
|
10712
10988
|
context2.process.exit(1, { silent: true });
|
|
10713
10989
|
return;
|
|
10714
10990
|
}
|
|
10715
|
-
|
|
10716
|
-
|
|
10991
|
+
for (const name of names) {
|
|
10992
|
+
if (env.has(name)) env.unset(name);
|
|
10717
10993
|
}
|
|
10718
|
-
env.unset(varName);
|
|
10719
10994
|
}
|
|
10720
10995
|
writeDescription(context2) {
|
|
10721
10996
|
const { writer, translator: t } = context2;
|
|
@@ -10723,7 +10998,7 @@ var CliUnsetCommandProcessor = class {
|
|
|
10723
10998
|
writer.writeln();
|
|
10724
10999
|
writer.writeln(t.t("cli.common.usage", "Usage:"));
|
|
10725
11000
|
writer.writeln(
|
|
10726
|
-
` ${writer.wrapInColor("unset VAR", cliCore.CliForegroundColor.Cyan)}`
|
|
11001
|
+
` ${writer.wrapInColor("unset VAR [VAR...]", cliCore.CliForegroundColor.Cyan)}`
|
|
10727
11002
|
);
|
|
10728
11003
|
}
|
|
10729
11004
|
};
|
|
@@ -10773,7 +11048,6 @@ var CliEnvCommandProcessor = class {
|
|
|
10773
11048
|
);
|
|
10774
11049
|
}
|
|
10775
11050
|
};
|
|
10776
|
-
var DEFAULT_FONT_SIZE = 20;
|
|
10777
11051
|
var MIN_FONT_SIZE = 8;
|
|
10778
11052
|
var MAX_FONT_SIZE = 40;
|
|
10779
11053
|
var STEP = 2;
|
|
@@ -10786,7 +11060,7 @@ var CliFontSizeCommandProcessor = class {
|
|
|
10786
11060
|
this.metadata = { icon: cliCore.CliIcon.Settings, module: "system" };
|
|
10787
11061
|
this.stateConfiguration = {
|
|
10788
11062
|
storeName: "font-size",
|
|
10789
|
-
initialState: {
|
|
11063
|
+
initialState: {}
|
|
10790
11064
|
};
|
|
10791
11065
|
this.processors = [
|
|
10792
11066
|
{
|
|
@@ -10805,9 +11079,9 @@ var CliFontSizeCommandProcessor = class {
|
|
|
10805
11079
|
},
|
|
10806
11080
|
{
|
|
10807
11081
|
command: "reset",
|
|
10808
|
-
description:
|
|
11082
|
+
description: "Reset font size to the default",
|
|
10809
11083
|
processCommand: async (_, context2) => {
|
|
10810
|
-
await this.
|
|
11084
|
+
await this.resetFontSize(context2);
|
|
10811
11085
|
}
|
|
10812
11086
|
},
|
|
10813
11087
|
{
|
|
@@ -10831,6 +11105,7 @@ var CliFontSizeCommandProcessor = class {
|
|
|
10831
11105
|
];
|
|
10832
11106
|
}
|
|
10833
11107
|
async initialize(context2) {
|
|
11108
|
+
this.hostFontSize = context2.terminal?.options?.fontSize;
|
|
10834
11109
|
const state = context2.state.getState();
|
|
10835
11110
|
if (state?.fontSize != null && context2.terminal?.options) {
|
|
10836
11111
|
context2.terminal.options.fontSize = state.fontSize;
|
|
@@ -10851,7 +11126,7 @@ var CliFontSizeCommandProcessor = class {
|
|
|
10851
11126
|
` ${context2.writer.wrapInColor("font-size set <n>", cliCore.CliForegroundColor.Cyan)} Set to exact size`
|
|
10852
11127
|
);
|
|
10853
11128
|
context2.writer.writeln(
|
|
10854
|
-
` ${context2.writer.wrapInColor("font-size reset", cliCore.CliForegroundColor.Cyan)} Reset to default (${
|
|
11129
|
+
` ${context2.writer.wrapInColor("font-size reset", cliCore.CliForegroundColor.Cyan)} Reset to default (${this.getDefault()}px)`
|
|
10855
11130
|
);
|
|
10856
11131
|
}
|
|
10857
11132
|
getCurrent(context2) {
|
|
@@ -10860,7 +11135,19 @@ var CliFontSizeCommandProcessor = class {
|
|
|
10860
11135
|
return fromTerminal;
|
|
10861
11136
|
}
|
|
10862
11137
|
const state = context2.state.getState();
|
|
10863
|
-
return state?.fontSize ??
|
|
11138
|
+
return state?.fontSize ?? this.getDefault();
|
|
11139
|
+
}
|
|
11140
|
+
getDefault() {
|
|
11141
|
+
return this.hostFontSize ?? defaultFontSize();
|
|
11142
|
+
}
|
|
11143
|
+
async resetFontSize(context2) {
|
|
11144
|
+
const size = this.getDefault();
|
|
11145
|
+
if (context2.terminal?.options) {
|
|
11146
|
+
context2.terminal.options.fontSize = size;
|
|
11147
|
+
}
|
|
11148
|
+
context2.state.updateState({ fontSize: void 0 });
|
|
11149
|
+
await context2.state.persist();
|
|
11150
|
+
context2.writer.writeSuccess(`Font size set to ${size}px`);
|
|
10864
11151
|
}
|
|
10865
11152
|
async setFontSize(context2, size) {
|
|
10866
11153
|
const clamped = Math.min(MAX_FONT_SIZE, Math.max(MIN_FONT_SIZE, size));
|
|
@@ -11811,6 +12098,7 @@ var CliTimerManager = class {
|
|
|
11811
12098
|
this.managedTimers.clear();
|
|
11812
12099
|
}
|
|
11813
12100
|
};
|
|
12101
|
+
var MIN_READABLE_COLUMN = 8;
|
|
11814
12102
|
var CliTerminalWriter = class {
|
|
11815
12103
|
constructor(terminal) {
|
|
11816
12104
|
this.terminal = terminal;
|
|
@@ -11942,6 +12230,24 @@ var CliTerminalWriter = class {
|
|
|
11942
12230
|
const indent = " ".repeat(level);
|
|
11943
12231
|
this.writeln(`${indent}${text}`);
|
|
11944
12232
|
}
|
|
12233
|
+
/** One block per row, header names as keys; used when a table cannot fit the terminal. */
|
|
12234
|
+
writeRecords(headers, rows) {
|
|
12235
|
+
const keyWidth = Math.max(...headers.map((h) => cliCore.visibleLength(h)));
|
|
12236
|
+
rows.forEach((row, index) => {
|
|
12237
|
+
if (index > 0) this.write("\r\n");
|
|
12238
|
+
headers.forEach((header, i) => {
|
|
12239
|
+
const value = row[i] ?? "";
|
|
12240
|
+
if (!header.trim()) {
|
|
12241
|
+
if (value.trim()) this.write(`${value}\r
|
|
12242
|
+
`);
|
|
12243
|
+
return;
|
|
12244
|
+
}
|
|
12245
|
+
const key = header + " ".repeat(keyWidth - cliCore.visibleLength(header));
|
|
12246
|
+
this.write(`${this.wrapInColor(key, cliCore.CliForegroundColor.Yellow)} : ${value}\r
|
|
12247
|
+
`);
|
|
12248
|
+
});
|
|
12249
|
+
});
|
|
12250
|
+
}
|
|
11945
12251
|
writeTable(headers, rows, options) {
|
|
11946
12252
|
const cols = this.terminal.cols;
|
|
11947
12253
|
const naturalWidths = headers.map(
|
|
@@ -11979,6 +12285,11 @@ var CliTerminalWriter = class {
|
|
|
11979
12285
|
used++;
|
|
11980
12286
|
}
|
|
11981
12287
|
}
|
|
12288
|
+
const tooNarrow = colWidths.reduce((s, w) => s + w, 0) > Math.max(available, 0) || colWidths.some((w, i) => w < Math.min(naturalWidths[i], MIN_READABLE_COLUMN));
|
|
12289
|
+
if (tooNarrow) {
|
|
12290
|
+
this.writeRecords(headers, rows);
|
|
12291
|
+
return;
|
|
12292
|
+
}
|
|
11982
12293
|
const truncateText = (text, maxWidth) => {
|
|
11983
12294
|
const t = text ?? "";
|
|
11984
12295
|
const vis = cliCore.visibleLength(t);
|
|
@@ -12416,6 +12727,10 @@ var InputModeBase = class {
|
|
|
12416
12727
|
* Cut a line to the terminal width. Lines redrawn in place must stay on one row:
|
|
12417
12728
|
* a wrapped line takes two rows and breaks the cursor-up arithmetic of the redraw.
|
|
12418
12729
|
*/
|
|
12730
|
+
/** A prompt label without a trailing colon, for modes that append their own ": ". */
|
|
12731
|
+
label(promptText) {
|
|
12732
|
+
return promptText.replace(/:\s*$/, "");
|
|
12733
|
+
}
|
|
12419
12734
|
fitLine(text) {
|
|
12420
12735
|
return cliCore.truncateToWidth(text, Math.max(1, this.host.getTerminalCols() - 1));
|
|
12421
12736
|
}
|
|
@@ -12590,6 +12905,7 @@ var ConfirmInputMode = class extends InputModeBase {
|
|
|
12590
12905
|
async handleInput(data) {
|
|
12591
12906
|
if (data === "\r") {
|
|
12592
12907
|
if (this.buffer === "") {
|
|
12908
|
+
this.host.terminal.write(this.defaultValue ? "y" : "n");
|
|
12593
12909
|
this.resolveAndPop(this.defaultValue);
|
|
12594
12910
|
} else {
|
|
12595
12911
|
const lower = this.buffer.toLowerCase();
|
|
@@ -12771,7 +13087,7 @@ var SelectInputMode = class extends InputModeBase {
|
|
|
12771
13087
|
const selectedOpt = this.options.find((o) => o.value === value);
|
|
12772
13088
|
const label = selectedOpt ? selectedOpt.label : value;
|
|
12773
13089
|
this.host.terminal.write("\x1B[2K\r");
|
|
12774
|
-
this.host.terminal.write(`\x1B[32m\u2714\x1B[0m ${this.promptText} \x1B[36m${label}\x1B[0m`);
|
|
13090
|
+
this.host.terminal.write(`\x1B[32m\u2714\x1B[0m ${this.label(this.promptText)}: \x1B[36m${label}\x1B[0m`);
|
|
12775
13091
|
this.host.terminal.write("\x1B[?25h");
|
|
12776
13092
|
super.resolveAndPop(value);
|
|
12777
13093
|
}
|
|
@@ -12781,7 +13097,7 @@ var SelectInputMode = class extends InputModeBase {
|
|
|
12781
13097
|
abort() {
|
|
12782
13098
|
this.clearRenderedLines();
|
|
12783
13099
|
this.host.terminal.write("\x1B[2K\r");
|
|
12784
|
-
this.host.terminal.write(`\x1B[33m\u2718\x1B[0m ${this.promptText} \x1B[2mcancelled\x1B[0m`);
|
|
13100
|
+
this.host.terminal.write(`\x1B[33m\u2718\x1B[0m ${this.label(this.promptText)}: \x1B[2mcancelled\x1B[0m`);
|
|
12785
13101
|
this.host.terminal.write("\x1B[?25h");
|
|
12786
13102
|
super.abort();
|
|
12787
13103
|
}
|
|
@@ -12942,15 +13258,15 @@ var SelectInputMode = class extends InputModeBase {
|
|
|
12942
13258
|
if (this.selectOptions?.searchable) {
|
|
12943
13259
|
if (this.filter.length > 0) {
|
|
12944
13260
|
this.host.terminal.write(
|
|
12945
|
-
this.fitLine(`\x1B[36m?\x1B[0m ${this.promptText}: ${this.filter}`)
|
|
13261
|
+
this.fitLine(`\x1B[36m?\x1B[0m ${this.label(this.promptText)}: ${this.filter}`)
|
|
12946
13262
|
);
|
|
12947
13263
|
} else {
|
|
12948
13264
|
this.host.terminal.write(
|
|
12949
|
-
this.fitLine(`\x1B[36m?\x1B[0m ${this.promptText}: \x1B[2mType to filter...\x1B[0m`)
|
|
13265
|
+
this.fitLine(`\x1B[36m?\x1B[0m ${this.label(this.promptText)}: \x1B[2mType to filter...\x1B[0m`)
|
|
12950
13266
|
);
|
|
12951
13267
|
}
|
|
12952
13268
|
} else {
|
|
12953
|
-
this.host.terminal.write(this.fitLine(`\x1B[36m?\x1B[0m ${this.promptText}:`));
|
|
13269
|
+
this.host.terminal.write(this.fitLine(`\x1B[36m?\x1B[0m ${this.label(this.promptText)}:`));
|
|
12954
13270
|
}
|
|
12955
13271
|
}
|
|
12956
13272
|
/**
|
|
@@ -13122,7 +13438,7 @@ var InlineSelectInputMode = class extends InputModeBase {
|
|
|
13122
13438
|
const selectedOpt = this.selectableOptions.find((o) => o.value === value);
|
|
13123
13439
|
const label = selectedOpt ? selectedOpt.label : value;
|
|
13124
13440
|
this.host.terminal.write("\x1B[2K\r");
|
|
13125
|
-
this.host.terminal.write(`\x1B[32m\u2714\x1B[0m ${this.promptText}: \x1B[36m${label}\x1B[0m`);
|
|
13441
|
+
this.host.terminal.write(`\x1B[32m\u2714\x1B[0m ${this.label(this.promptText)}: \x1B[36m${label}\x1B[0m`);
|
|
13126
13442
|
this.host.terminal.write("\x1B[?25h");
|
|
13127
13443
|
super.resolveAndPop(value);
|
|
13128
13444
|
}
|
|
@@ -13132,7 +13448,7 @@ var InlineSelectInputMode = class extends InputModeBase {
|
|
|
13132
13448
|
abort() {
|
|
13133
13449
|
this.clearExtraLines();
|
|
13134
13450
|
this.host.terminal.write("\x1B[2K\r");
|
|
13135
|
-
this.host.terminal.write(`\x1B[33m\u2718\x1B[0m ${this.promptText}: \x1B[2mcancelled\x1B[0m`);
|
|
13451
|
+
this.host.terminal.write(`\x1B[33m\u2718\x1B[0m ${this.label(this.promptText)}: \x1B[2mcancelled\x1B[0m`);
|
|
13136
13452
|
this.host.terminal.write("\x1B[?25h");
|
|
13137
13453
|
super.abort();
|
|
13138
13454
|
}
|
|
@@ -13172,13 +13488,13 @@ var InlineSelectInputMode = class extends InputModeBase {
|
|
|
13172
13488
|
* Get the prompt prefix string (without ANSI escapes for width calculation).
|
|
13173
13489
|
*/
|
|
13174
13490
|
getPromptPrefix() {
|
|
13175
|
-
return `? ${this.promptText}: `;
|
|
13491
|
+
return `? ${this.label(this.promptText)}: `;
|
|
13176
13492
|
}
|
|
13177
13493
|
/**
|
|
13178
13494
|
* Get the rendered prompt prefix (with ANSI color codes).
|
|
13179
13495
|
*/
|
|
13180
13496
|
getRenderedPromptPrefix() {
|
|
13181
|
-
return `\x1B[36m?\x1B[0m ${this.promptText}: `;
|
|
13497
|
+
return `\x1B[36m?\x1B[0m ${this.label(this.promptText)}: `;
|
|
13182
13498
|
}
|
|
13183
13499
|
/**
|
|
13184
13500
|
* Calculate the width needed for a single option.
|
|
@@ -13375,7 +13691,7 @@ var MultiSelectInputMode = class extends InputModeBase {
|
|
|
13375
13691
|
});
|
|
13376
13692
|
const summary = labels.length > 0 ? labels.join(", ") : "none";
|
|
13377
13693
|
this.host.terminal.write("\x1B[2K\r");
|
|
13378
|
-
this.host.terminal.write(`\x1B[32m\u2714\x1B[0m ${this.promptText} \x1B[36m${summary}\x1B[0m`);
|
|
13694
|
+
this.host.terminal.write(`\x1B[32m\u2714\x1B[0m ${this.label(this.promptText)}: \x1B[36m${summary}\x1B[0m`);
|
|
13379
13695
|
this.host.terminal.write("\x1B[?25h");
|
|
13380
13696
|
super.resolveAndPop(value);
|
|
13381
13697
|
}
|
|
@@ -13385,7 +13701,7 @@ var MultiSelectInputMode = class extends InputModeBase {
|
|
|
13385
13701
|
abort() {
|
|
13386
13702
|
this.clearRenderedLines();
|
|
13387
13703
|
this.host.terminal.write("\x1B[2K\r");
|
|
13388
|
-
this.host.terminal.write(`\x1B[33m\u2718\x1B[0m ${this.promptText} \x1B[2mcancelled\x1B[0m`);
|
|
13704
|
+
this.host.terminal.write(`\x1B[33m\u2718\x1B[0m ${this.label(this.promptText)}: \x1B[2mcancelled\x1B[0m`);
|
|
13389
13705
|
this.host.terminal.write("\x1B[?25h");
|
|
13390
13706
|
super.abort();
|
|
13391
13707
|
}
|
|
@@ -13559,15 +13875,15 @@ var MultiSelectInputMode = class extends InputModeBase {
|
|
|
13559
13875
|
if (this.selectOptions?.searchable) {
|
|
13560
13876
|
if (this.filter.length > 0) {
|
|
13561
13877
|
this.host.terminal.write(
|
|
13562
|
-
this.fitLine(`\x1B[36m?\x1B[0m ${this.promptText}: ${this.filter}`)
|
|
13878
|
+
this.fitLine(`\x1B[36m?\x1B[0m ${this.label(this.promptText)}: ${this.filter}`)
|
|
13563
13879
|
);
|
|
13564
13880
|
} else {
|
|
13565
13881
|
this.host.terminal.write(
|
|
13566
|
-
this.fitLine(`\x1B[36m?\x1B[0m ${this.promptText}: \x1B[2mType to filter...\x1B[0m`)
|
|
13882
|
+
this.fitLine(`\x1B[36m?\x1B[0m ${this.label(this.promptText)}: \x1B[2mType to filter...\x1B[0m`)
|
|
13567
13883
|
);
|
|
13568
13884
|
}
|
|
13569
13885
|
} else {
|
|
13570
|
-
this.host.terminal.write(this.fitLine(`\x1B[36m?\x1B[0m ${this.promptText}:`));
|
|
13886
|
+
this.host.terminal.write(this.fitLine(`\x1B[36m?\x1B[0m ${this.label(this.promptText)}:`));
|
|
13571
13887
|
}
|
|
13572
13888
|
}
|
|
13573
13889
|
/**
|
|
@@ -13902,13 +14218,13 @@ var FileInputMode = class extends InputModeBase {
|
|
|
13902
14218
|
this.waiting = false;
|
|
13903
14219
|
if (!results || this.isResolved) {
|
|
13904
14220
|
this.host.terminal.write("\x1B[2K\r");
|
|
13905
|
-
this.host.writeToTerminal(`\x1B[36m?\x1B[0m ${this.promptText}: \x1B[2m(cancelled)\x1B[0m\r
|
|
14221
|
+
this.host.writeToTerminal(`\x1B[36m?\x1B[0m ${this.label(this.promptText)}: \x1B[2m(cancelled)\x1B[0m\r
|
|
13906
14222
|
`);
|
|
13907
14223
|
if (!this.isResolved) this.abort();
|
|
13908
14224
|
return;
|
|
13909
14225
|
}
|
|
13910
14226
|
this.host.terminal.write("\x1B[2K\r");
|
|
13911
|
-
this.host.writeToTerminal(`\x1B[36m?\x1B[0m ${this.promptText}:\r
|
|
14227
|
+
this.host.writeToTerminal(`\x1B[36m?\x1B[0m ${this.label(this.promptText)}:\r
|
|
13912
14228
|
`);
|
|
13913
14229
|
let totalSize = 0;
|
|
13914
14230
|
for (const file of results) {
|
|
@@ -13926,7 +14242,7 @@ var FileInputMode = class extends InputModeBase {
|
|
|
13926
14242
|
this.waiting = false;
|
|
13927
14243
|
if (this.isResolved) return;
|
|
13928
14244
|
this.host.terminal.write("\x1B[2K\r");
|
|
13929
|
-
this.host.writeToTerminal(`\x1B[36m?\x1B[0m ${this.promptText}: \x1B[31m(error)\x1B[0m\r
|
|
14245
|
+
this.host.writeToTerminal(`\x1B[36m?\x1B[0m ${this.label(this.promptText)}: \x1B[31m(error)\x1B[0m\r
|
|
13930
14246
|
`);
|
|
13931
14247
|
this.abort();
|
|
13932
14248
|
}
|
|
@@ -15396,7 +15712,7 @@ function substituteVars(input, variables) {
|
|
|
15396
15712
|
);
|
|
15397
15713
|
return result;
|
|
15398
15714
|
}
|
|
15399
|
-
function expandEnvironmentVars(command2, context2) {
|
|
15715
|
+
function expandEnvironmentVars(command2, context2, lastExitCode) {
|
|
15400
15716
|
const env = context2.services.get(ICliEnvironment_TOKEN);
|
|
15401
15717
|
if (!env) {
|
|
15402
15718
|
return command2;
|
|
@@ -15404,6 +15720,9 @@ function expandEnvironmentVars(command2, context2) {
|
|
|
15404
15720
|
const parts = command2.split("'");
|
|
15405
15721
|
for (let i = 0; i < parts.length; i++) {
|
|
15406
15722
|
if (i % 2 === 0) {
|
|
15723
|
+
if (lastExitCode !== void 0) {
|
|
15724
|
+
parts[i] = parts[i].replace(/\$\?/g, String(lastExitCode));
|
|
15725
|
+
}
|
|
15407
15726
|
parts[i] = parts[i].replace(
|
|
15408
15727
|
/\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g,
|
|
15409
15728
|
(_, name) => env.get(name) ?? ""
|
|
@@ -15412,17 +15731,30 @@ function expandEnvironmentVars(command2, context2) {
|
|
|
15412
15731
|
/\$([A-Za-z_][A-Za-z0-9_]*)/g,
|
|
15413
15732
|
(_, name) => env.get(name) ?? ""
|
|
15414
15733
|
);
|
|
15734
|
+
const home = env.get("HOME");
|
|
15735
|
+
if (home) {
|
|
15736
|
+
parts[i] = parts[i].replace(
|
|
15737
|
+
/(^|\s)~(?=\/|\s|$)/g,
|
|
15738
|
+
(match, before, offset) => i > 0 && offset === 0 && !before ? match : `${before}${home}`
|
|
15739
|
+
);
|
|
15740
|
+
}
|
|
15415
15741
|
}
|
|
15416
15742
|
}
|
|
15417
15743
|
return parts.join("'");
|
|
15418
15744
|
}
|
|
15419
15745
|
|
|
15420
15746
|
// src/lib/executor/cli-command-executor.ts
|
|
15747
|
+
function toExitStatus(code) {
|
|
15748
|
+
if (code === void 0) return 0;
|
|
15749
|
+
return code < 0 ? 1 : code;
|
|
15750
|
+
}
|
|
15421
15751
|
var CliCommandExecutor = class {
|
|
15422
15752
|
constructor(registry) {
|
|
15423
15753
|
this.registry = registry;
|
|
15424
15754
|
this.commandParser = new CommandParser();
|
|
15425
15755
|
this.globalParameters = [];
|
|
15756
|
+
/** Exit status of the last command, expanded as `$?` (0 = success). */
|
|
15757
|
+
this.lastExitCode = 0;
|
|
15426
15758
|
this.registerGlobalParameter(versionGlobalParameter);
|
|
15427
15759
|
this.registerGlobalParameter(helpGlobalParameter);
|
|
15428
15760
|
this.registerGlobalParameter(contextGlobalParameter);
|
|
@@ -15526,6 +15858,7 @@ var CliCommandExecutor = class {
|
|
|
15526
15858
|
rootContext
|
|
15527
15859
|
);
|
|
15528
15860
|
lastExitSuccess = context2.process.exitCode === void 0 || context2.process.exitCode === 0;
|
|
15861
|
+
this.lastExitCode = toExitStatus(context2.process.exitCode);
|
|
15529
15862
|
rootContext.lastCommandResult = {
|
|
15530
15863
|
command: part.value,
|
|
15531
15864
|
success: lastExitSuccess
|
|
@@ -15533,6 +15866,7 @@ var CliCommandExecutor = class {
|
|
|
15533
15866
|
pipelineData = context2.process.data;
|
|
15534
15867
|
} catch (e) {
|
|
15535
15868
|
lastExitSuccess = false;
|
|
15869
|
+
this.lastExitCode = 1;
|
|
15536
15870
|
rootContext.lastCommandResult = {
|
|
15537
15871
|
command: part.value,
|
|
15538
15872
|
success: false
|
|
@@ -15548,7 +15882,7 @@ var CliCommandExecutor = class {
|
|
|
15548
15882
|
}
|
|
15549
15883
|
async executeSingleCommand(command2, data, context2) {
|
|
15550
15884
|
const process = context2.process;
|
|
15551
|
-
command2 = expandEnvironmentVars(command2, context2);
|
|
15885
|
+
command2 = expandEnvironmentVars(command2, context2, this.lastExitCode);
|
|
15552
15886
|
const assignMatch = command2.match(/^([A-Za-z_][A-Za-z0-9_]*)=(.*)$/);
|
|
15553
15887
|
if (assignMatch) {
|
|
15554
15888
|
const env = context2.services.get(ICliEnvironment_TOKEN);
|
|
@@ -16604,30 +16938,6 @@ var CliDefaultPingServerService = class {
|
|
|
16604
16938
|
return new Promise((resolve) => setTimeout(resolve, 2e3));
|
|
16605
16939
|
}
|
|
16606
16940
|
};
|
|
16607
|
-
var CliDragDropService = class {
|
|
16608
|
-
constructor(_container) {
|
|
16609
|
-
this._container = _container;
|
|
16610
|
-
this._subject = new rxjs.Subject();
|
|
16611
|
-
this._dragOver = (e) => e.preventDefault();
|
|
16612
|
-
this._drop = (e) => {
|
|
16613
|
-
e.preventDefault();
|
|
16614
|
-
const files = Array.from(e.dataTransfer?.files ?? []);
|
|
16615
|
-
if (files.length > 0) {
|
|
16616
|
-
this._subject.next(files);
|
|
16617
|
-
}
|
|
16618
|
-
};
|
|
16619
|
-
this._container.addEventListener("dragover", this._dragOver);
|
|
16620
|
-
this._container.addEventListener("drop", this._drop);
|
|
16621
|
-
}
|
|
16622
|
-
get onFileDrop() {
|
|
16623
|
-
return this._subject.asObservable();
|
|
16624
|
-
}
|
|
16625
|
-
destroy() {
|
|
16626
|
-
this._container.removeEventListener("dragover", this._dragOver);
|
|
16627
|
-
this._container.removeEventListener("drop", this._drop);
|
|
16628
|
-
this._subject.complete();
|
|
16629
|
-
}
|
|
16630
|
-
};
|
|
16631
16941
|
|
|
16632
16942
|
// src/lib/services/cli-permission-registry.ts
|
|
16633
16943
|
var CliPermissionRegistry = class {
|
|
@@ -16652,62 +16962,6 @@ var CliPermissionRegistry = class {
|
|
|
16652
16962
|
}
|
|
16653
16963
|
};
|
|
16654
16964
|
|
|
16655
|
-
// src/lib/addons/overlay.ts
|
|
16656
|
-
var OverlayAddon = class {
|
|
16657
|
-
constructor() {
|
|
16658
|
-
this.overlayNode = document.createElement("div");
|
|
16659
|
-
this.overlayNode.style.cssText = `border-radius: 15px;
|
|
16660
|
-
font-size: xx-large;
|
|
16661
|
-
opacity: 0.75;
|
|
16662
|
-
padding: 0.2em 0.5em 0.2em 0.5em;
|
|
16663
|
-
position: absolute;
|
|
16664
|
-
-webkit-user-select: none;
|
|
16665
|
-
-webkit-transition: opacity 180ms ease-in;
|
|
16666
|
-
-moz-user-select: none;
|
|
16667
|
-
-moz-transition: opacity 180ms ease-in;`;
|
|
16668
|
-
this.overlayNode.addEventListener(
|
|
16669
|
-
"mousedown",
|
|
16670
|
-
(e) => {
|
|
16671
|
-
e.preventDefault();
|
|
16672
|
-
e.stopPropagation();
|
|
16673
|
-
},
|
|
16674
|
-
true
|
|
16675
|
-
);
|
|
16676
|
-
}
|
|
16677
|
-
activate(terminal) {
|
|
16678
|
-
this.terminal = terminal;
|
|
16679
|
-
}
|
|
16680
|
-
dispose() {
|
|
16681
|
-
}
|
|
16682
|
-
showOverlay(msg, timeout) {
|
|
16683
|
-
const { terminal, overlayNode } = this;
|
|
16684
|
-
if (!terminal.element) return;
|
|
16685
|
-
overlayNode.style.color = "#101010";
|
|
16686
|
-
overlayNode.style.backgroundColor = "#f0f0f0";
|
|
16687
|
-
overlayNode.textContent = msg;
|
|
16688
|
-
overlayNode.style.opacity = "0.75";
|
|
16689
|
-
if (!overlayNode.parentNode) {
|
|
16690
|
-
terminal.element.appendChild(overlayNode);
|
|
16691
|
-
}
|
|
16692
|
-
const divSize = terminal.element.getBoundingClientRect();
|
|
16693
|
-
const overlaySize = overlayNode.getBoundingClientRect();
|
|
16694
|
-
overlayNode.style.top = (divSize.height - overlaySize.height) / 2 + "px";
|
|
16695
|
-
overlayNode.style.left = (divSize.width - overlaySize.width) / 2 + "px";
|
|
16696
|
-
if (this.overlayTimeout) clearTimeout(this.overlayTimeout);
|
|
16697
|
-
if (!timeout) return;
|
|
16698
|
-
this.overlayTimeout = window.setTimeout(() => {
|
|
16699
|
-
overlayNode.style.opacity = "0";
|
|
16700
|
-
this.overlayTimeout = window.setTimeout(() => {
|
|
16701
|
-
if (overlayNode.parentNode) {
|
|
16702
|
-
overlayNode.parentNode.removeChild(overlayNode);
|
|
16703
|
-
}
|
|
16704
|
-
this.overlayTimeout = void 0;
|
|
16705
|
-
overlayNode.style.opacity = "0.75";
|
|
16706
|
-
}, 200);
|
|
16707
|
-
}, timeout || 1500);
|
|
16708
|
-
}
|
|
16709
|
-
};
|
|
16710
|
-
|
|
16711
16965
|
// src/lib/storage/cli-key-value-store.ts
|
|
16712
16966
|
var CliKeyValueStore = class {
|
|
16713
16967
|
constructor() {
|
|
@@ -17882,61 +18136,6 @@ function createServerModule() {
|
|
|
17882
18136
|
services: []
|
|
17883
18137
|
};
|
|
17884
18138
|
}
|
|
17885
|
-
function getTerminalOptions(userOptions) {
|
|
17886
|
-
return {
|
|
17887
|
-
cursorBlink: true,
|
|
17888
|
-
allowProposedApi: true,
|
|
17889
|
-
fontSize: 20,
|
|
17890
|
-
theme: cliCore.DefaultThemes.default,
|
|
17891
|
-
convertEol: true,
|
|
17892
|
-
...userOptions ?? {}
|
|
17893
|
-
};
|
|
17894
|
-
}
|
|
17895
|
-
function initializeTerminal(container, opts) {
|
|
17896
|
-
const terminal = new xterm.Terminal(opts);
|
|
17897
|
-
const fitAddon = new addonFit.FitAddon();
|
|
17898
|
-
terminal.loadAddon(fitAddon);
|
|
17899
|
-
terminal.loadAddon(new addonWebLinks.WebLinksAddon());
|
|
17900
|
-
terminal.loadAddon(new OverlayAddon());
|
|
17901
|
-
terminal.loadAddon(new addonUnicode11.Unicode11Addon());
|
|
17902
|
-
const serializeAddon = new addonSerialize.SerializeAddon();
|
|
17903
|
-
terminal.loadAddon(serializeAddon);
|
|
17904
|
-
terminal.open(container);
|
|
17905
|
-
fitAddon.fit();
|
|
17906
|
-
requestAnimationFrame(() => fitAddon.fit());
|
|
17907
|
-
if (document.fonts?.ready) {
|
|
17908
|
-
document.fonts.ready.then(() => {
|
|
17909
|
-
requestAnimationFrame(() => fitAddon.fit());
|
|
17910
|
-
});
|
|
17911
|
-
}
|
|
17912
|
-
container.classList.add("terminal-container");
|
|
17913
|
-
container.style.background = opts.theme?.background ?? "#000";
|
|
17914
|
-
const wheelListener = (e) => e.preventDefault();
|
|
17915
|
-
container.addEventListener("wheel", wheelListener, { passive: false });
|
|
17916
|
-
terminal.focus();
|
|
17917
|
-
const dragDropService = new CliDragDropService(container);
|
|
17918
|
-
return { terminal, fitAddon, serializeAddon, dragDropService, wheelListener };
|
|
17919
|
-
}
|
|
17920
|
-
var LAYOUT_TIMEOUT_MS = 1e4;
|
|
17921
|
-
function waitForLayout(container) {
|
|
17922
|
-
return new Promise((resolve, reject) => {
|
|
17923
|
-
const deadline = Date.now() + LAYOUT_TIMEOUT_MS;
|
|
17924
|
-
const check = () => {
|
|
17925
|
-
if (container.offsetWidth > 0 && container.offsetHeight > 0) {
|
|
17926
|
-
resolve();
|
|
17927
|
-
return;
|
|
17928
|
-
}
|
|
17929
|
-
if (Date.now() >= deadline) {
|
|
17930
|
-
reject(new Error(
|
|
17931
|
-
`CliEngine.start(): container has zero dimensions after ${LAYOUT_TIMEOUT_MS}ms. Ensure the container element is visible and laid out before calling start().`
|
|
17932
|
-
));
|
|
17933
|
-
return;
|
|
17934
|
-
}
|
|
17935
|
-
requestAnimationFrame(check);
|
|
17936
|
-
};
|
|
17937
|
-
check();
|
|
17938
|
-
});
|
|
17939
|
-
}
|
|
17940
18139
|
|
|
17941
18140
|
// src/lib/editor/syntax/registry.ts
|
|
17942
18141
|
var SyntaxHighlighterRegistry = class {
|
|
@@ -18328,6 +18527,14 @@ var CliEngine = class {
|
|
|
18328
18527
|
{ ...this.options ?? {}, terminalOptions: terminalOpts }
|
|
18329
18528
|
);
|
|
18330
18529
|
this.executionContext.initializeTerminalListeners();
|
|
18530
|
+
const environment = services.get(ICliEnvironment_TOKEN);
|
|
18531
|
+
if (environment instanceof CliEnvironment) {
|
|
18532
|
+
const ctx = this.executionContext;
|
|
18533
|
+
environment.bind("USER", () => ctx.userSession?.user.name);
|
|
18534
|
+
environment.bind("HOME", () => ctx.userSession?.user.homeDir);
|
|
18535
|
+
environment.bind("PWD", () => ctx.promptPathProvider?.());
|
|
18536
|
+
environment.setProfileResolver(() => ctx.userSession?.user.name);
|
|
18537
|
+
}
|
|
18331
18538
|
this.executionContext.backgroundServices.setProcessRegistry(processRegistry);
|
|
18332
18539
|
services.set([{
|
|
18333
18540
|
provide: CliBackgroundServiceRegistry_TOKEN,
|
|
@@ -19033,6 +19240,7 @@ exports.builtinProcessors = builtinProcessors;
|
|
|
19033
19240
|
exports.computeDiff = computeDiff;
|
|
19034
19241
|
exports.contextGlobalParameter = contextGlobalParameter;
|
|
19035
19242
|
exports.createServerModule = createServerModule;
|
|
19243
|
+
exports.defaultFontSize = defaultFontSize;
|
|
19036
19244
|
exports.describeShellClose = describeShellClose;
|
|
19037
19245
|
exports.executeOnServer = executeOnServer;
|
|
19038
19246
|
exports.expandEnvironmentVars = expandEnvironmentVars;
|
|
@@ -19050,6 +19258,7 @@ exports.initializeTerminal = initializeTerminal;
|
|
|
19050
19258
|
exports.isWasmAccelerated = isWasmAccelerated;
|
|
19051
19259
|
exports.miscProcessors = miscProcessors;
|
|
19052
19260
|
exports.openLink = openLink;
|
|
19261
|
+
exports.parseAssignments = parseAssignments;
|
|
19053
19262
|
exports.reconcileArgs = reconcileArgs;
|
|
19054
19263
|
exports.renderServerResponse = renderServerResponse;
|
|
19055
19264
|
exports.renderSingleOutput = renderSingleOutput;
|