@qodalis/cli-core 2.1.1 → 2.3.0

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/public-api.js CHANGED
@@ -2599,7 +2599,7 @@ function satisfiesVersionRange(installed, range) {
2599
2599
  }
2600
2600
 
2601
2601
  // src/lib/version.ts
2602
- var LIBRARY_VERSION = "2.1.1";
2602
+ var LIBRARY_VERSION = "2.3.0";
2603
2603
  var API_VERSION = 2;
2604
2604
 
2605
2605
  // src/lib/utils/server-version-negotiator.ts
@@ -2724,576 +2724,6 @@ function appendQueryParams(url, params) {
2724
2724
  return `${url}${url.includes("?") ? "&" : "?"}${query}`;
2725
2725
  }
2726
2726
 
2727
- // src/lib/utils/panel-theme-sync.ts
2728
- function hexToRgb(hex) {
2729
- const m = /^#?([0-9A-Fa-f]{6})([0-9A-Fa-f]{2})?$/.exec(hex);
2730
- if (!m) return null;
2731
- const n = parseInt(m[1], 16);
2732
- return { r: n >> 16 & 255, g: n >> 8 & 255, b: n & 255 };
2733
- }
2734
- function shiftColor(hex, amount) {
2735
- const rgb = hexToRgb(hex);
2736
- if (!rgb) return hex;
2737
- const r = Math.min(255, Math.max(0, rgb.r + Math.round(amount)));
2738
- const g = Math.min(255, Math.max(0, rgb.g + Math.round(amount)));
2739
- const b = Math.min(255, Math.max(0, rgb.b + Math.round(amount)));
2740
- return `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`;
2741
- }
2742
- function hexToRgba(hex, alpha) {
2743
- const rgb = hexToRgb(hex);
2744
- if (!rgb) return hex;
2745
- return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${alpha})`;
2746
- }
2747
- var DEFAULT_BG = "#111827";
2748
- var DEFAULT_FG = "#ffffff";
2749
- var DEFAULT_ACCENT = "#818cf8";
2750
- function derivePanelThemeStyles(theme) {
2751
- const bg = theme.background || DEFAULT_BG;
2752
- const fg = theme.foreground || DEFAULT_FG;
2753
- const accent = theme.cyan || theme.blue || theme.magenta || DEFAULT_ACCENT;
2754
- return {
2755
- "--cli-panel-bg": bg,
2756
- "--cli-panel-header-bg": shiftColor(bg, 12),
2757
- "--cli-panel-border": shiftColor(bg, 24),
2758
- "--cli-panel-text": fg,
2759
- "--cli-panel-text-secondary": hexToRgba(fg, 0.6),
2760
- "--cli-panel-accent": accent,
2761
- "--cli-btn-hover-bg": hexToRgba(accent, 0.12),
2762
- "--cli-btn-active-bg": hexToRgba(accent, 0.2)
2763
- };
2764
- }
2765
-
2766
- // src/lib/utils/panel-position-store.ts
2767
- var STORAGE_KEY = "cli-panel-position";
2768
- var POSITION_CYCLE = ["bottom", "right", "top", "left"];
2769
- function loadPanelPosition() {
2770
- try {
2771
- const stored = localStorage.getItem(STORAGE_KEY);
2772
- if (stored && POSITION_CYCLE.includes(stored)) {
2773
- return stored;
2774
- }
2775
- } catch {
2776
- }
2777
- return null;
2778
- }
2779
- function savePanelPosition(position) {
2780
- try {
2781
- localStorage.setItem(STORAGE_KEY, position);
2782
- } catch {
2783
- }
2784
- }
2785
- function nextPanelPosition(current) {
2786
- const index = POSITION_CYCLE.indexOf(current);
2787
- if (index === -1) {
2788
- return POSITION_CYCLE[0];
2789
- }
2790
- return POSITION_CYCLE[(index + 1) % POSITION_CYCLE.length];
2791
- }
2792
-
2793
- // src/lib/utils/ansi-utils.ts
2794
- var ANSI_RE = /\x1b\[[0-9;]*m/g;
2795
- function stripAnsi(text) {
2796
- return text.replace(ANSI_RE, "");
2797
- }
2798
- function visibleLength(text) {
2799
- const stripped = stripAnsi(text);
2800
- let width = 0;
2801
- for (const ch of stripped) {
2802
- const cp = ch.codePointAt(0);
2803
- if (cp >= 65024 && cp <= 65039) continue;
2804
- if (cp === 8205) continue;
2805
- if (cp >= 768 && cp <= 879) continue;
2806
- width += isWideCharacter(cp) ? 2 : 1;
2807
- }
2808
- return width;
2809
- }
2810
- function truncateToWidth(text, width, ellipsis = "\u2026") {
2811
- if (width < 1) return "";
2812
- if (visibleLength(text) <= width) return text;
2813
- const room = Math.max(0, width - visibleLength(ellipsis));
2814
- let out = "";
2815
- let used = 0;
2816
- let i = 0;
2817
- while (i < text.length) {
2818
- if (text[i] === "\x1B") {
2819
- const m = /^\x1b\[[0-9;]*m/.exec(text.slice(i));
2820
- if (m) {
2821
- out += m[0];
2822
- i += m[0].length;
2823
- continue;
2824
- }
2825
- }
2826
- const ch = String.fromCodePoint(text.codePointAt(i));
2827
- const w = visibleLength(ch);
2828
- if (used + w > room) break;
2829
- out += ch;
2830
- used += w;
2831
- i += ch.length;
2832
- }
2833
- return `${out}${ellipsis}\x1B[0m`;
2834
- }
2835
- function isWideCharacter(cp) {
2836
- if (cp >= 126976) return true;
2837
- if (cp >= 9728 && cp <= 10175) return true;
2838
- if (cp >= 9984 && cp <= 10175) return true;
2839
- if (cp >= 19968 && cp <= 40959) return true;
2840
- if (cp >= 63744 && cp <= 64255) return true;
2841
- if (cp >= 65281 && cp <= 65376) return true;
2842
- if (cp >= 65504 && cp <= 65510) return true;
2843
- if (cp >= 11904 && cp <= 12255) return true;
2844
- if (cp >= 12288 && cp <= 12543) return true;
2845
- if (cp >= 12800 && cp <= 13055) return true;
2846
- if (cp >= 13056 && cp <= 13311) return true;
2847
- if (cp >= 127232 && cp <= 127487) return true;
2848
- if (cp >= 8960 && cp <= 9215) return true;
2849
- return false;
2850
- }
2851
-
2852
- // src/lib/utils/access-guards.ts
2853
- var list = (value) => Array.isArray(value) ? value.filter((v) => typeof v === "string" && v.trim()) : [];
2854
- var authorization = (context) => {
2855
- try {
2856
- return context.services.get(ICliAuthorizationService_TOKEN);
2857
- } catch {
2858
- return void 0;
2859
- }
2860
- };
2861
- function chain(processor) {
2862
- const out = [];
2863
- let current = processor;
2864
- while (current && out.length < 32 && !out.includes(current)) {
2865
- out.push(current);
2866
- current = current.parent;
2867
- }
2868
- return out;
2869
- }
2870
- var requiredPermissionsOf = (p) => [...new Set(chain(p).flatMap((x) => list(x.metadata?.requiredPermissions)))];
2871
- var requiredGroupLevels = (p) => chain(p).map((x) => list(x.metadata?.requiredGroups)).filter((g) => g.length > 0);
2872
- var needsAuth = (p) => chain(p).some((x) => x.metadata?.requireAuth === true) || requiredGroupLevels(p).length > 0 || requiredPermissionsOf(p).length > 0;
2873
- var cliRequireAuthGuard = {
2874
- name: "access:require-auth",
2875
- priority: -100,
2876
- appliesTo: (processor, _command, context) => needsAuth(processor) && !!authorization(context),
2877
- canActivate: (_command, processor, context) => authorization(context).getPrincipal() ? true : `${processor.command}: login required`
2878
- };
2879
- var cliRequiredGroupsGuard = {
2880
- name: "access:required-groups",
2881
- priority: -90,
2882
- appliesTo: (processor, _command, context) => requiredGroupLevels(processor).length > 0 && !!authorization(context),
2883
- canActivate: (_command, processor, context) => {
2884
- const auth = authorization(context);
2885
- const principal = auth.getPrincipal();
2886
- if (!principal) return `${processor.command}: login required`;
2887
- if (auth.can("*")) return true;
2888
- for (const required of requiredGroupLevels(processor)) {
2889
- const member = required.some((g) => principal.groups.some((pg) => pg.toLowerCase() === g.toLowerCase()));
2890
- if (!member) return `${processor.command}: permission denied (requires group: ${required.join(" or ")})`;
2891
- }
2892
- return true;
2893
- }
2894
- };
2895
- var cliRequiredPermissionsGuard = {
2896
- name: "access:required-permissions",
2897
- priority: -80,
2898
- appliesTo: (processor, _command, context) => requiredPermissionsOf(processor).length > 0 && !!authorization(context),
2899
- canActivate: (_command, processor, context) => {
2900
- const principal = authorization(context).getPrincipal();
2901
- if (!principal) return `${processor.command}: login required`;
2902
- const missing = cliMissingPermissions(principal.permissions, requiredPermissionsOf(processor));
2903
- return missing.length === 0 ? true : `${processor.command}: permission denied (requires ${missing.join(", ")})`;
2904
- }
2905
- };
2906
- var cliAccessMetadataGuards = [
2907
- cliRequireAuthGuard,
2908
- cliRequiredGroupsGuard,
2909
- cliRequiredPermissionsGuard
2910
- ];
2911
-
2912
- // src/lib/utils/server-target.ts
2913
- function cliDefaultServer(context) {
2914
- const servers = context.options?.servers ?? [];
2915
- const manager = context.services?.get(ICliServerManager_TOKEN);
2916
- const preferred = manager?.preferredServer?.();
2917
- return (preferred ? servers.find((s) => s.name === preferred) : void 0) ?? servers[0];
2918
- }
2919
-
2920
- // src/lib/utils/help-format.ts
2921
- function writeColumns(context, rows, formatLeft, formatRight) {
2922
- const width = Math.max(...rows.map(([left]) => left.length)) + 2;
2923
- for (const [left, right] of rows) {
2924
- context.writer.writeln(
2925
- ` ${formatLeft(left.padEnd(width))}${formatRight(right)}`
2926
- );
2927
- }
2928
- }
2929
- function writeUsage(context, rows) {
2930
- const { writer, translator } = context;
2931
- writer.writeln(`\u{1F4CB} ${translator.t("cli.common.usage", "Usage:")}`);
2932
- writeColumns(
2933
- context,
2934
- rows,
2935
- (cmd) => writer.wrapInColor(cmd, "\x1B[36m" /* Cyan */),
2936
- (text) => text
2937
- );
2938
- }
2939
- function writeExamples(context, rows) {
2940
- const { writer, translator } = context;
2941
- writer.writeln(`\u{1F4DD} ${translator.t("cli.common.examples", "Examples:")}`);
2942
- writeColumns(
2943
- context,
2944
- rows,
2945
- (cmd) => cmd,
2946
- (comment) => writer.wrapInColor(`# ${comment}`, "\x1B[32m" /* Green */)
2947
- );
2948
- }
2949
- function writeWrapped(context, text, indent = 0) {
2950
- const cols = context.terminal?.cols ?? 80;
2951
- const width = Math.max(20, Math.min(cols - 1, 100) - indent);
2952
- const pad = " ".repeat(indent);
2953
- let line = "";
2954
- for (const word of text.split(/\s+/).filter(Boolean)) {
2955
- if (line && visibleLength2(line) + 1 + visibleLength2(word) > width) {
2956
- context.writer.writeln(pad + line);
2957
- line = word;
2958
- } else {
2959
- line = line ? `${line} ${word}` : word;
2960
- }
2961
- }
2962
- if (line) context.writer.writeln(pad + line);
2963
- }
2964
- function visibleLength2(text) {
2965
- return text.replace(/\x1b\[[0-9;]*m/g, "").length;
2966
- }
2967
- function writeHint(context, command, action) {
2968
- const { writer, translator } = context;
2969
- const text = `\u{1F4A1} ${translator.t("cli.common.use_hint", "Use {command} {action}", {
2970
- command: writer.wrapInColor(command, "\x1B[36m" /* Cyan */),
2971
- action
2972
- })}`;
2973
- const width = Math.min((context.terminal?.cols ?? 80) - 1, 100) - 3;
2974
- if (visibleLength2(text) + 1 <= width) {
2975
- writer.writeInfo(text);
2976
- return;
2977
- }
2978
- const lines = [];
2979
- let line = "";
2980
- for (const word of text.split(" ")) {
2981
- if (line && visibleLength2(line) + 1 + visibleLength2(word) > width) {
2982
- lines.push(line);
2983
- line = word;
2984
- } else {
2985
- line = line ? `${line} ${word}` : word;
2986
- }
2987
- }
2988
- if (line) lines.push(line);
2989
- writer.writeInfo(lines[0]);
2990
- for (const rest of lines.slice(1)) {
2991
- writer.writeln(` ${rest}`);
2992
- }
2993
- }
2994
-
2995
- // src/lib/utils/raw-argument.ts
2996
- function unquoteRawArgument(text) {
2997
- const value = text.trim();
2998
- if (value.length < 2) return value;
2999
- const quote = value[0];
3000
- if (quote === "'") {
3001
- return value.indexOf("'", 1) === value.length - 1 ? value.slice(1, -1) : value;
3002
- }
3003
- if (quote === '"') {
3004
- for (let i = 1; i < value.length; i++) {
3005
- if (value[i] === "\\") i++;
3006
- else if (value[i] === '"') {
3007
- return i === value.length - 1 ? value.slice(1, -1).replace(/\\(["\\$`])/g, "$1") : value;
3008
- }
3009
- }
3010
- }
3011
- return value;
3012
- }
3013
-
3014
- // src/lib/utils/index.ts
3015
- var getParameterValue = (p, args) => {
3016
- if (args[p.name] !== void 0) {
3017
- return args[p.name];
3018
- }
3019
- const matchedAlias = p.aliases?.find((alias) => args[alias] !== void 0);
3020
- return matchedAlias ? args[matchedAlias] : void 0;
3021
- };
3022
- var formatJson = (json) => {
3023
- const identedJson = JSON.stringify(json, null, 2);
3024
- return colorizeJson(identedJson.split("\n").join("\r\n"));
3025
- };
3026
- var colorizeJson = (jsonString) => {
3027
- const RST = "\x1B[0m";
3028
- const CYN = "\x1B[36m";
3029
- const GRN = "\x1B[32m";
3030
- const YLW = "\x1B[33m";
3031
- const GRY = "\x1B[90m";
3032
- const tokenRe = /("(?:[^"\\]|\\.)*"?)(\s*:)?|(\btrue\b|\bfalse\b|\bnull\b)|(-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)|([{}[\],])/g;
3033
- let result = "";
3034
- let lastIndex = 0;
3035
- let m;
3036
- while ((m = tokenRe.exec(jsonString)) !== null) {
3037
- if (m.index > lastIndex) {
3038
- result += jsonString.slice(lastIndex, m.index);
3039
- }
3040
- if (m[1] !== void 0) {
3041
- if (m[2] !== void 0) {
3042
- result += CYN + m[1] + RST + m[2];
3043
- } else {
3044
- result += GRN + m[1] + RST;
3045
- }
3046
- } else if (m[3] !== void 0) {
3047
- result += YLW + m[3] + RST;
3048
- } else if (m[4] !== void 0) {
3049
- result += YLW + m[4] + RST;
3050
- } else if (m[5] !== void 0) {
3051
- result += GRY + m[5] + RST;
3052
- }
3053
- lastIndex = m.index + m[0].length;
3054
- }
3055
- if (lastIndex < jsonString.length) {
3056
- result += jsonString.slice(lastIndex);
3057
- }
3058
- return result;
3059
- };
3060
- var toQueryString = (params) => {
3061
- const searchParams = new URLSearchParams();
3062
- for (const [key, value] of Object.entries(params)) {
3063
- if (Array.isArray(value)) {
3064
- value.forEach((v) => searchParams.append(key, v.toString()));
3065
- } else if (value !== null && value !== void 0) {
3066
- searchParams.append(key, value.toString());
3067
- }
3068
- }
3069
- return searchParams.toString();
3070
- };
3071
- var highlightTextWithBg = (text, pattern, bgColor = "\x1B[43m" /* Yellow */) => {
3072
- return text.replace(
3073
- pattern,
3074
- (match) => `${bgColor}${match}${"\x1B[0m" /* Reset */}`
3075
- );
3076
- };
3077
- var getRightOfWord = (command, word) => {
3078
- const index = command.indexOf(word);
3079
- if (index !== -1) {
3080
- return command.slice(index + word.length).trim();
3081
- }
3082
- return void 0;
3083
- };
3084
- var colorFirstWord = (text, colorFunction) => {
3085
- if (!text) return text;
3086
- const match = text.match(/^(\s*)(\S+)(.*)$/);
3087
- if (!match) return text;
3088
- const [, leadingSpaces, firstWord, restOfText] = match;
3089
- const firstWordColored = colorFunction(firstWord);
3090
- return `${leadingSpaces}${firstWordColored}${restOfText}`;
3091
- };
3092
- var utils = {
3093
- getParameterValue,
3094
- formatJson,
3095
- colorizeJson,
3096
- toQueryString,
3097
- highlightTextWithBg,
3098
- getRightOfWord,
3099
- colorFirstWord,
3100
- ObjectDescriber,
3101
- delay,
3102
- getConfigValue,
3103
- getPluginConfigValue,
3104
- resolveConfigurationCategories,
3105
- CLI_CONFIGURE_STORE_NAME
3106
- };
3107
-
3108
- // src/lib/modules/cli-module-registry.ts
3109
- var CliModuleRegistry = class {
3110
- constructor() {
3111
- this.modules = /* @__PURE__ */ new Map();
3112
- this.bootHandlers = [];
3113
- this.unregisterHandlers = [];
3114
- /** Registrations whose boot handlers are still running. */
3115
- this.inFlight = /* @__PURE__ */ new Set();
3116
- }
3117
- /**
3118
- * Register a handler that is called whenever a new module is registered.
3119
- */
3120
- onModuleBoot(handler) {
3121
- this.bootHandlers.push(handler);
3122
- }
3123
- /**
3124
- * Register a web plugin module and notify all boot handlers.
3125
- * Modules whose `apiVersion` is below the runtime's `API_VERSION` are
3126
- * skipped with a warning — this ensures only compatible frontend plugins load.
3127
- */
3128
- register(module) {
3129
- const registration = this.registerInternal(module);
3130
- this.inFlight.add(registration);
3131
- const done = () => this.inFlight.delete(registration);
3132
- registration.then(done, done);
3133
- return registration;
3134
- }
3135
- /**
3136
- * Resolve once every registration in progress (including ones started
3137
- * meanwhile, e.g. a plugin loading another) has finished booting.
3138
- */
3139
- async whenIdle() {
3140
- while (this.inFlight.size > 0) {
3141
- await Promise.allSettled([...this.inFlight]);
3142
- }
3143
- }
3144
- async registerInternal(module) {
3145
- const modApiVersion = module.apiVersion;
3146
- if (typeof modApiVersion !== "number" || modApiVersion < API_VERSION) {
3147
- const msg = `[CLI] Plugin "${module.name}" targets API version ${modApiVersion ?? "unknown"}, but this runtime requires API version ${API_VERSION}. Skipping.`;
3148
- if (this.onWarn) {
3149
- this.onWarn(msg);
3150
- } else {
3151
- console.warn(msg);
3152
- }
3153
- return;
3154
- }
3155
- this.modules.set(module.name, module);
3156
- for (const handler of this.bootHandlers) {
3157
- try {
3158
- await handler(module);
3159
- } catch (e) {
3160
- const msg = `[CLI] Boot handler failed for module "${module.name}": ${e instanceof Error ? e.message : e}`;
3161
- if (this.onWarn) {
3162
- this.onWarn(msg);
3163
- } else {
3164
- console.warn(msg);
3165
- }
3166
- }
3167
- }
3168
- }
3169
- /**
3170
- * Register a handler that is called when a module is unregistered,
3171
- * e.g. so its processors can be removed.
3172
- */
3173
- onModuleUnregister(handler) {
3174
- this.unregisterHandlers.push(handler);
3175
- }
3176
- /**
3177
- * Unregister a module and notify all unregister handlers. A module
3178
- * registered again afterwards (e.g. a newer version) boots again.
3179
- * Returns the removed module, or `undefined` when it was not registered.
3180
- */
3181
- unregister(name) {
3182
- const module = this.modules.get(name);
3183
- if (!module) return void 0;
3184
- this.modules.delete(name);
3185
- for (const handler of this.unregisterHandlers) {
3186
- try {
3187
- handler(module);
3188
- } catch (e) {
3189
- const msg = `[CLI] Unregister handler failed for module "${name}": ${e instanceof Error ? e.message : e}`;
3190
- if (this.onWarn) {
3191
- this.onWarn(msg);
3192
- } else {
3193
- console.warn(msg);
3194
- }
3195
- }
3196
- }
3197
- return module;
3198
- }
3199
- /**
3200
- * Get a module by name.
3201
- */
3202
- getModule(name) {
3203
- return this.modules.get(name);
3204
- }
3205
- /**
3206
- * Get all registered modules.
3207
- */
3208
- getAll() {
3209
- return Array.from(this.modules.values());
3210
- }
3211
- /**
3212
- * Track a module without triggering boot handlers.
3213
- * Used by the boot service for statically-provided modules that are
3214
- * already being booted through the normal pipeline.
3215
- */
3216
- track(module) {
3217
- this.modules.set(module.name, module);
3218
- }
3219
- /**
3220
- * Check if a module is registered.
3221
- */
3222
- has(name) {
3223
- return this.modules.has(name);
3224
- }
3225
- };
3226
-
3227
- // src/lib/modules/index.ts
3228
- var initializeBrowserEnvironment = ({
3229
- context,
3230
- registry
3231
- }) => {
3232
- window.__cliModuleRegistry = registry;
3233
- window.cliCore = {
3234
- ...constants,
3235
- ...utils,
3236
- ...enums,
3237
- bootCliModule
3238
- };
3239
- Object.defineProperty(window, "ngCore", {
3240
- configurable: true,
3241
- get() {
3242
- console.warn(
3243
- "CLI: Angular decorators are not supported in UMD modules. Use plain classes instead."
3244
- );
3245
- return { Injectable: () => () => {
3246
- } };
3247
- }
3248
- });
3249
- };
3250
- var bootCliModule = async (module) => {
3251
- if (typeof window !== "undefined" && window.__cliModuleRegistry) {
3252
- await window.__cliModuleRegistry.register(module);
3253
- }
3254
- };
3255
-
3256
- // src/lib/types/CancellablePromise.ts
3257
- var CANCELLATION_ERROR_MESSAGE = "Promise cancelled";
3258
- var CancellablePromise = class {
3259
- constructor(executor) {
3260
- this.executor = executor;
3261
- this.hasCancelled = false;
3262
- this.abortController = new AbortController();
3263
- }
3264
- /**
3265
- * Run the executor and return a promise for its result.
3266
- * If `cancel()` has been called, the promise rejects immediately.
3267
- */
3268
- execute() {
3269
- return new Promise((resolve, reject) => {
3270
- this.abortController.signal.onabort = () => {
3271
- reject(new Error(CANCELLATION_ERROR_MESSAGE));
3272
- };
3273
- this.executor(
3274
- (value) => {
3275
- if (!this.hasCancelled) {
3276
- resolve(value);
3277
- }
3278
- },
3279
- (reason) => {
3280
- if (!this.hasCancelled) {
3281
- reject(reason);
3282
- }
3283
- }
3284
- );
3285
- });
3286
- }
3287
- /**
3288
- * Cancel the promise. The executing promise rejects with
3289
- * `Error('Promise cancelled')` and subsequent resolve/reject calls are ignored.
3290
- */
3291
- cancel() {
3292
- this.hasCancelled = true;
3293
- this.abortController.abort();
3294
- }
3295
- };
3296
-
3297
2727
  // src/lib/themes/default-themes.ts
3298
2728
  var DefaultThemes = {
3299
2729
  default: {
@@ -3319,6 +2749,31 @@ var DefaultThemes = {
3319
2749
  brightCyan: "#a5f3fc",
3320
2750
  brightWhite: "#f1f5f9"
3321
2751
  },
2752
+ // Soft grey paper and slate text; every color reads at 4.5:1 or more on the background
2753
+ light: {
2754
+ background: "#f7f8fa",
2755
+ foreground: "#334155",
2756
+ cursor: "#4f46e5",
2757
+ cursorAccent: "#f7f8fa",
2758
+ selectionBackground: "#d9def7",
2759
+ selectionForeground: "#1e293b",
2760
+ black: "#334155",
2761
+ red: "#c93c37",
2762
+ green: "#2c7a4b",
2763
+ yellow: "#946200",
2764
+ blue: "#3d5bd9",
2765
+ magenta: "#8b3fc7",
2766
+ cyan: "#0e7586",
2767
+ white: "#5b6577",
2768
+ brightBlack: "#667085",
2769
+ brightRed: "#b42a25",
2770
+ brightGreen: "#1f6a3d",
2771
+ brightYellow: "#7a5100",
2772
+ brightBlue: "#2f47bd",
2773
+ brightMagenta: "#7431ad",
2774
+ brightCyan: "#0a6170",
2775
+ brightWhite: "#1e293b"
2776
+ },
3322
2777
  classic: {
3323
2778
  background: "#0c0c0c",
3324
2779
  foreground: "#cccccc",
@@ -3929,7 +3384,680 @@ var DefaultThemes = {
3929
3384
  brightWhite: "#ffffff"
3930
3385
  }
3931
3386
  };
3932
- DefaultThemes.yellow = DefaultThemes.highContrastLight;
3387
+ DefaultThemes.yellow = DefaultThemes.highContrastLight;
3388
+
3389
+ // src/lib/utils/panel-theme-sync.ts
3390
+ function hexToRgb(hex) {
3391
+ const short = /^#?([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f])$/.exec(hex);
3392
+ if (short) hex = short.slice(1).map((c) => c + c).join("");
3393
+ const m = /^#?([0-9A-Fa-f]{6})([0-9A-Fa-f]{2})?$/.exec(hex);
3394
+ if (!m) return null;
3395
+ const n = parseInt(m[1], 16);
3396
+ return { r: n >> 16 & 255, g: n >> 8 & 255, b: n & 255 };
3397
+ }
3398
+ function shiftColor(hex, amount) {
3399
+ const rgb = hexToRgb(hex);
3400
+ if (!rgb) return hex;
3401
+ const r = Math.min(255, Math.max(0, rgb.r + Math.round(amount)));
3402
+ const g = Math.min(255, Math.max(0, rgb.g + Math.round(amount)));
3403
+ const b = Math.min(255, Math.max(0, rgb.b + Math.round(amount)));
3404
+ return `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`;
3405
+ }
3406
+ function hexToRgba(hex, alpha) {
3407
+ const rgb = hexToRgb(hex);
3408
+ if (!rgb) return hex;
3409
+ return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${alpha})`;
3410
+ }
3411
+ function colorSchemeOf(color) {
3412
+ const rgb = color ? hexToRgb(color) : null;
3413
+ if (!rgb) return "dark";
3414
+ const channel = (v) => {
3415
+ const c = v / 255;
3416
+ return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
3417
+ };
3418
+ const luminance = 0.2126 * channel(rgb.r) + 0.7152 * channel(rgb.g) + 0.0722 * channel(rgb.b);
3419
+ return luminance > 0.4 ? "light" : "dark";
3420
+ }
3421
+ var CliPanelPalettes = Object.freeze({
3422
+ dark: Object.freeze({
3423
+ background: "#070b14",
3424
+ headerBackground: "#0f1623",
3425
+ border: "#1e293b",
3426
+ text: "#e2e8f0",
3427
+ textSecondary: "#94a3b8",
3428
+ accent: "#818cf8",
3429
+ hoverBackground: "rgba(129, 140, 248, 0.12)",
3430
+ activeBackground: "rgba(129, 140, 248, 0.22)",
3431
+ danger: "#f87171",
3432
+ shadow: "rgba(0, 0, 0, 0.45)"
3433
+ }),
3434
+ // Soft grey paper instead of pure white, slate text rather than black: easier on the eyes
3435
+ light: Object.freeze({
3436
+ background: "#f7f8fa",
3437
+ headerBackground: "#eceff3",
3438
+ border: "#d9dee6",
3439
+ text: "#1e293b",
3440
+ textSecondary: "#5b6577",
3441
+ accent: "#4f46e5",
3442
+ hoverBackground: "rgba(30, 41, 59, 0.06)",
3443
+ activeBackground: "rgba(79, 70, 229, 0.12)",
3444
+ danger: "#c93c37",
3445
+ shadow: "rgba(15, 23, 42, 0.12)"
3446
+ })
3447
+ });
3448
+ var PALETTE_TERMINALS = {
3449
+ dark: DefaultThemes.default,
3450
+ light: DefaultThemes.light
3451
+ };
3452
+ function derivePanelColors(theme) {
3453
+ const scheme = colorSchemeOf(theme.background);
3454
+ const palette = CliPanelPalettes[scheme];
3455
+ const bg = theme.background || palette.background;
3456
+ const fg = theme.foreground || palette.text;
3457
+ const accent = theme.cyan || theme.blue || theme.magenta || palette.accent;
3458
+ const light = scheme === "light";
3459
+ return {
3460
+ background: bg,
3461
+ headerBackground: shiftColor(bg, light ? -8 : 12),
3462
+ border: shiftColor(bg, light ? -28 : 24),
3463
+ text: fg,
3464
+ textSecondary: hexToRgba(fg, 0.65),
3465
+ accent,
3466
+ hoverBackground: hexToRgba(accent, light ? 0.1 : 0.12),
3467
+ activeBackground: hexToRgba(accent, light ? 0.16 : 0.2),
3468
+ danger: theme.red || palette.danger,
3469
+ shadow: palette.shadow
3470
+ };
3471
+ }
3472
+ function panelColorStyles(colors) {
3473
+ return {
3474
+ "--cli-panel-bg": colors.background,
3475
+ "--cli-panel-header-bg": colors.headerBackground,
3476
+ "--cli-panel-border": colors.border,
3477
+ "--cli-panel-text": colors.text,
3478
+ "--cli-panel-text-secondary": colors.textSecondary,
3479
+ "--cli-panel-accent": colors.accent,
3480
+ "--cli-btn-hover-bg": colors.hoverBackground,
3481
+ "--cli-btn-active-bg": colors.activeBackground,
3482
+ "--cli-panel-danger": colors.danger,
3483
+ "--cli-panel-shadow": colors.shadow
3484
+ };
3485
+ }
3486
+ function derivePanelThemeStyles(theme) {
3487
+ return {
3488
+ ...panelColorStyles(derivePanelColors(theme)),
3489
+ "color-scheme": colorSchemeOf(theme.background)
3490
+ };
3491
+ }
3492
+ function resolvePanelTheme(input, prefersDark, themes = DefaultThemes) {
3493
+ const pick = (scheme2) => scheme2 === "auto" ? prefersDark ? "dark" : "light" : scheme2;
3494
+ const lookup = (name) => themes[name];
3495
+ let scheme;
3496
+ let terminal;
3497
+ let colors;
3498
+ let font;
3499
+ let radius;
3500
+ if (input === void 0 || input === "dark" || input === "light" || input === "auto") {
3501
+ scheme = pick(input ?? "dark");
3502
+ terminal = PALETTE_TERMINALS[scheme];
3503
+ colors = { ...CliPanelPalettes[scheme] };
3504
+ } else if (typeof input === "string") {
3505
+ const named = lookup(input);
3506
+ terminal = named ?? PALETTE_TERMINALS.dark;
3507
+ scheme = colorSchemeOf(terminal.background);
3508
+ colors = named ? derivePanelColors(named) : { ...CliPanelPalettes.dark };
3509
+ } else {
3510
+ const custom = typeof input.terminal === "string" ? lookup(input.terminal) : input.terminal;
3511
+ scheme = input.base ? pick(input.base) : custom ? colorSchemeOf(custom.background) : "dark";
3512
+ terminal = custom ?? PALETTE_TERMINALS[scheme];
3513
+ colors = custom ? derivePanelColors(custom) : { ...CliPanelPalettes[scheme] };
3514
+ if (input.colors) colors = { ...colors, ...stripUndefined(input.colors) };
3515
+ font = input.fontFamily;
3516
+ radius = input.radius;
3517
+ }
3518
+ const styles = { ...panelColorStyles(colors), "color-scheme": scheme };
3519
+ if (font) styles["--cli-panel-font"] = font;
3520
+ if (radius) styles["--cli-panel-radius"] = radius;
3521
+ return { scheme, styles, terminal };
3522
+ }
3523
+ function stripUndefined(value) {
3524
+ return Object.fromEntries(Object.entries(value).filter(([, v]) => v !== void 0));
3525
+ }
3526
+ function prefersDarkScheme() {
3527
+ if (typeof window === "undefined" || !window.matchMedia) return true;
3528
+ return window.matchMedia("(prefers-color-scheme: dark)").matches;
3529
+ }
3530
+
3531
+ // src/lib/utils/panel-position-store.ts
3532
+ var STORAGE_KEY = "cli-panel-position";
3533
+ var POSITION_CYCLE = ["bottom", "right", "top", "left"];
3534
+ function loadPanelPosition() {
3535
+ try {
3536
+ const stored = localStorage.getItem(STORAGE_KEY);
3537
+ if (stored && POSITION_CYCLE.includes(stored)) {
3538
+ return stored;
3539
+ }
3540
+ } catch {
3541
+ }
3542
+ return null;
3543
+ }
3544
+ function savePanelPosition(position) {
3545
+ try {
3546
+ localStorage.setItem(STORAGE_KEY, position);
3547
+ } catch {
3548
+ }
3549
+ }
3550
+ function nextPanelPosition(current) {
3551
+ const index = POSITION_CYCLE.indexOf(current);
3552
+ if (index === -1) {
3553
+ return POSITION_CYCLE[0];
3554
+ }
3555
+ return POSITION_CYCLE[(index + 1) % POSITION_CYCLE.length];
3556
+ }
3557
+
3558
+ // src/lib/utils/ansi-utils.ts
3559
+ var ANSI_RE = /\x1b\[[0-9;]*m/g;
3560
+ function stripAnsi(text) {
3561
+ return text.replace(ANSI_RE, "");
3562
+ }
3563
+ function visibleLength(text) {
3564
+ const stripped = stripAnsi(text);
3565
+ let width = 0;
3566
+ for (const ch of stripped) {
3567
+ const cp = ch.codePointAt(0);
3568
+ if (cp >= 65024 && cp <= 65039) continue;
3569
+ if (cp === 8205) continue;
3570
+ if (cp >= 768 && cp <= 879) continue;
3571
+ width += isWideCharacter(cp) ? 2 : 1;
3572
+ }
3573
+ return width;
3574
+ }
3575
+ function truncateToWidth(text, width, ellipsis = "\u2026") {
3576
+ if (width < 1) return "";
3577
+ if (visibleLength(text) <= width) return text;
3578
+ const room = Math.max(0, width - visibleLength(ellipsis));
3579
+ let out = "";
3580
+ let used = 0;
3581
+ let i = 0;
3582
+ while (i < text.length) {
3583
+ if (text[i] === "\x1B") {
3584
+ const m = /^\x1b\[[0-9;]*m/.exec(text.slice(i));
3585
+ if (m) {
3586
+ out += m[0];
3587
+ i += m[0].length;
3588
+ continue;
3589
+ }
3590
+ }
3591
+ const ch = String.fromCodePoint(text.codePointAt(i));
3592
+ const w = visibleLength(ch);
3593
+ if (used + w > room) break;
3594
+ out += ch;
3595
+ used += w;
3596
+ i += ch.length;
3597
+ }
3598
+ return `${out}${ellipsis}\x1B[0m`;
3599
+ }
3600
+ function isWideCharacter(cp) {
3601
+ if (cp >= 126976) return true;
3602
+ if (cp >= 9728 && cp <= 10175) return true;
3603
+ if (cp >= 9984 && cp <= 10175) return true;
3604
+ if (cp >= 19968 && cp <= 40959) return true;
3605
+ if (cp >= 63744 && cp <= 64255) return true;
3606
+ if (cp >= 65281 && cp <= 65376) return true;
3607
+ if (cp >= 65504 && cp <= 65510) return true;
3608
+ if (cp >= 11904 && cp <= 12255) return true;
3609
+ if (cp >= 12288 && cp <= 12543) return true;
3610
+ if (cp >= 12800 && cp <= 13055) return true;
3611
+ if (cp >= 13056 && cp <= 13311) return true;
3612
+ if (cp >= 127232 && cp <= 127487) return true;
3613
+ if (cp >= 8960 && cp <= 9215) return true;
3614
+ return false;
3615
+ }
3616
+
3617
+ // src/lib/utils/access-guards.ts
3618
+ var list = (value) => Array.isArray(value) ? value.filter((v) => typeof v === "string" && v.trim()) : [];
3619
+ var authorization = (context) => {
3620
+ try {
3621
+ return context.services.get(ICliAuthorizationService_TOKEN);
3622
+ } catch {
3623
+ return void 0;
3624
+ }
3625
+ };
3626
+ function chain(processor) {
3627
+ const out = [];
3628
+ let current = processor;
3629
+ while (current && out.length < 32 && !out.includes(current)) {
3630
+ out.push(current);
3631
+ current = current.parent;
3632
+ }
3633
+ return out;
3634
+ }
3635
+ var requiredPermissionsOf = (p) => [...new Set(chain(p).flatMap((x) => list(x.metadata?.requiredPermissions)))];
3636
+ var requiredGroupLevels = (p) => chain(p).map((x) => list(x.metadata?.requiredGroups)).filter((g) => g.length > 0);
3637
+ var needsAuth = (p) => chain(p).some((x) => x.metadata?.requireAuth === true) || requiredGroupLevels(p).length > 0 || requiredPermissionsOf(p).length > 0;
3638
+ var cliRequireAuthGuard = {
3639
+ name: "access:require-auth",
3640
+ priority: -100,
3641
+ appliesTo: (processor, _command, context) => needsAuth(processor) && !!authorization(context),
3642
+ canActivate: (_command, processor, context) => authorization(context).getPrincipal() ? true : `${processor.command}: login required`
3643
+ };
3644
+ var cliRequiredGroupsGuard = {
3645
+ name: "access:required-groups",
3646
+ priority: -90,
3647
+ appliesTo: (processor, _command, context) => requiredGroupLevels(processor).length > 0 && !!authorization(context),
3648
+ canActivate: (_command, processor, context) => {
3649
+ const auth = authorization(context);
3650
+ const principal = auth.getPrincipal();
3651
+ if (!principal) return `${processor.command}: login required`;
3652
+ if (auth.can("*")) return true;
3653
+ for (const required of requiredGroupLevels(processor)) {
3654
+ const member = required.some((g) => principal.groups.some((pg) => pg.toLowerCase() === g.toLowerCase()));
3655
+ if (!member) return `${processor.command}: permission denied (requires group: ${required.join(" or ")})`;
3656
+ }
3657
+ return true;
3658
+ }
3659
+ };
3660
+ var cliRequiredPermissionsGuard = {
3661
+ name: "access:required-permissions",
3662
+ priority: -80,
3663
+ appliesTo: (processor, _command, context) => requiredPermissionsOf(processor).length > 0 && !!authorization(context),
3664
+ canActivate: (_command, processor, context) => {
3665
+ const principal = authorization(context).getPrincipal();
3666
+ if (!principal) return `${processor.command}: login required`;
3667
+ const missing = cliMissingPermissions(principal.permissions, requiredPermissionsOf(processor));
3668
+ return missing.length === 0 ? true : `${processor.command}: permission denied (requires ${missing.join(", ")})`;
3669
+ }
3670
+ };
3671
+ var cliAccessMetadataGuards = [
3672
+ cliRequireAuthGuard,
3673
+ cliRequiredGroupsGuard,
3674
+ cliRequiredPermissionsGuard
3675
+ ];
3676
+
3677
+ // src/lib/utils/server-target.ts
3678
+ function cliDefaultServer(context) {
3679
+ const servers = context.options?.servers ?? [];
3680
+ const manager = context.services?.get(ICliServerManager_TOKEN);
3681
+ const preferred = manager?.preferredServer?.();
3682
+ return (preferred ? servers.find((s) => s.name === preferred) : void 0) ?? servers[0];
3683
+ }
3684
+
3685
+ // src/lib/utils/help-format.ts
3686
+ function writeColumns(context, rows, formatLeft, formatRight) {
3687
+ const width = Math.max(...rows.map(([left]) => left.length)) + 2;
3688
+ for (const [left, right] of rows) {
3689
+ context.writer.writeln(
3690
+ ` ${formatLeft(left.padEnd(width))}${formatRight(right)}`
3691
+ );
3692
+ }
3693
+ }
3694
+ function writeUsage(context, rows) {
3695
+ const { writer, translator } = context;
3696
+ writer.writeln(`\u{1F4CB} ${translator.t("cli.common.usage", "Usage:")}`);
3697
+ writeColumns(
3698
+ context,
3699
+ rows,
3700
+ (cmd) => writer.wrapInColor(cmd, "\x1B[36m" /* Cyan */),
3701
+ (text) => text
3702
+ );
3703
+ }
3704
+ function writeExamples(context, rows) {
3705
+ const { writer, translator } = context;
3706
+ writer.writeln(`\u{1F4DD} ${translator.t("cli.common.examples", "Examples:")}`);
3707
+ writeColumns(
3708
+ context,
3709
+ rows,
3710
+ (cmd) => cmd,
3711
+ (comment) => writer.wrapInColor(`# ${comment}`, "\x1B[32m" /* Green */)
3712
+ );
3713
+ }
3714
+ function writeWrapped(context, text, indent = 0) {
3715
+ const cols = context.terminal?.cols ?? 80;
3716
+ const width = Math.max(20, Math.min(cols - 1, 100) - indent);
3717
+ const pad = " ".repeat(indent);
3718
+ let line = "";
3719
+ for (const word of text.split(/\s+/).filter(Boolean)) {
3720
+ if (line && visibleLength2(line) + 1 + visibleLength2(word) > width) {
3721
+ context.writer.writeln(pad + line);
3722
+ line = word;
3723
+ } else {
3724
+ line = line ? `${line} ${word}` : word;
3725
+ }
3726
+ }
3727
+ if (line) context.writer.writeln(pad + line);
3728
+ }
3729
+ function visibleLength2(text) {
3730
+ return text.replace(/\x1b\[[0-9;]*m/g, "").length;
3731
+ }
3732
+ function writeHint(context, command, action) {
3733
+ const { writer, translator } = context;
3734
+ const text = `\u{1F4A1} ${translator.t("cli.common.use_hint", "Use {command} {action}", {
3735
+ command: writer.wrapInColor(command, "\x1B[36m" /* Cyan */),
3736
+ action
3737
+ })}`;
3738
+ const width = Math.min((context.terminal?.cols ?? 80) - 1, 100) - 3;
3739
+ if (visibleLength2(text) + 1 <= width) {
3740
+ writer.writeInfo(text);
3741
+ return;
3742
+ }
3743
+ const lines = [];
3744
+ let line = "";
3745
+ for (const word of text.split(" ")) {
3746
+ if (line && visibleLength2(line) + 1 + visibleLength2(word) > width) {
3747
+ lines.push(line);
3748
+ line = word;
3749
+ } else {
3750
+ line = line ? `${line} ${word}` : word;
3751
+ }
3752
+ }
3753
+ if (line) lines.push(line);
3754
+ writer.writeInfo(lines[0]);
3755
+ for (const rest of lines.slice(1)) {
3756
+ writer.writeln(` ${rest}`);
3757
+ }
3758
+ }
3759
+
3760
+ // src/lib/utils/raw-argument.ts
3761
+ function unquoteRawArgument(text) {
3762
+ const value = text.trim();
3763
+ if (value.length < 2) return value;
3764
+ const quote = value[0];
3765
+ if (quote === "'") {
3766
+ return value.indexOf("'", 1) === value.length - 1 ? value.slice(1, -1) : value;
3767
+ }
3768
+ if (quote === '"') {
3769
+ for (let i = 1; i < value.length; i++) {
3770
+ if (value[i] === "\\") i++;
3771
+ else if (value[i] === '"') {
3772
+ return i === value.length - 1 ? value.slice(1, -1).replace(/\\(["\\$`])/g, "$1") : value;
3773
+ }
3774
+ }
3775
+ }
3776
+ return value;
3777
+ }
3778
+
3779
+ // src/lib/utils/index.ts
3780
+ var getParameterValue = (p, args) => {
3781
+ if (args[p.name] !== void 0) {
3782
+ return args[p.name];
3783
+ }
3784
+ const matchedAlias = p.aliases?.find((alias) => args[alias] !== void 0);
3785
+ return matchedAlias ? args[matchedAlias] : void 0;
3786
+ };
3787
+ var formatJson = (json) => {
3788
+ const identedJson = JSON.stringify(json, null, 2);
3789
+ return colorizeJson(identedJson.split("\n").join("\r\n"));
3790
+ };
3791
+ var colorizeJson = (jsonString) => {
3792
+ const RST = "\x1B[0m";
3793
+ const CYN = "\x1B[36m";
3794
+ const GRN = "\x1B[32m";
3795
+ const YLW = "\x1B[33m";
3796
+ const GRY = "\x1B[90m";
3797
+ const tokenRe = /("(?:[^"\\]|\\.)*"?)(\s*:)?|(\btrue\b|\bfalse\b|\bnull\b)|(-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)|([{}[\],])/g;
3798
+ let result = "";
3799
+ let lastIndex = 0;
3800
+ let m;
3801
+ while ((m = tokenRe.exec(jsonString)) !== null) {
3802
+ if (m.index > lastIndex) {
3803
+ result += jsonString.slice(lastIndex, m.index);
3804
+ }
3805
+ if (m[1] !== void 0) {
3806
+ if (m[2] !== void 0) {
3807
+ result += CYN + m[1] + RST + m[2];
3808
+ } else {
3809
+ result += GRN + m[1] + RST;
3810
+ }
3811
+ } else if (m[3] !== void 0) {
3812
+ result += YLW + m[3] + RST;
3813
+ } else if (m[4] !== void 0) {
3814
+ result += YLW + m[4] + RST;
3815
+ } else if (m[5] !== void 0) {
3816
+ result += GRY + m[5] + RST;
3817
+ }
3818
+ lastIndex = m.index + m[0].length;
3819
+ }
3820
+ if (lastIndex < jsonString.length) {
3821
+ result += jsonString.slice(lastIndex);
3822
+ }
3823
+ return result;
3824
+ };
3825
+ var toQueryString = (params) => {
3826
+ const searchParams = new URLSearchParams();
3827
+ for (const [key, value] of Object.entries(params)) {
3828
+ if (Array.isArray(value)) {
3829
+ value.forEach((v) => searchParams.append(key, v.toString()));
3830
+ } else if (value !== null && value !== void 0) {
3831
+ searchParams.append(key, value.toString());
3832
+ }
3833
+ }
3834
+ return searchParams.toString();
3835
+ };
3836
+ var highlightTextWithBg = (text, pattern, bgColor = "\x1B[43m" /* Yellow */) => {
3837
+ return text.replace(
3838
+ pattern,
3839
+ (match) => `${bgColor}${match}${"\x1B[0m" /* Reset */}`
3840
+ );
3841
+ };
3842
+ var getRightOfWord = (command, word) => {
3843
+ const index = command.indexOf(word);
3844
+ if (index !== -1) {
3845
+ return command.slice(index + word.length).trim();
3846
+ }
3847
+ return void 0;
3848
+ };
3849
+ var colorFirstWord = (text, colorFunction) => {
3850
+ if (!text) return text;
3851
+ const match = text.match(/^(\s*)(\S+)(.*)$/);
3852
+ if (!match) return text;
3853
+ const [, leadingSpaces, firstWord, restOfText] = match;
3854
+ const firstWordColored = colorFunction(firstWord);
3855
+ return `${leadingSpaces}${firstWordColored}${restOfText}`;
3856
+ };
3857
+ var utils = {
3858
+ getParameterValue,
3859
+ formatJson,
3860
+ colorizeJson,
3861
+ toQueryString,
3862
+ highlightTextWithBg,
3863
+ getRightOfWord,
3864
+ colorFirstWord,
3865
+ ObjectDescriber,
3866
+ delay,
3867
+ getConfigValue,
3868
+ getPluginConfigValue,
3869
+ resolveConfigurationCategories,
3870
+ CLI_CONFIGURE_STORE_NAME
3871
+ };
3872
+
3873
+ // src/lib/modules/cli-module-registry.ts
3874
+ var CliModuleRegistry = class {
3875
+ constructor() {
3876
+ this.modules = /* @__PURE__ */ new Map();
3877
+ this.bootHandlers = [];
3878
+ this.unregisterHandlers = [];
3879
+ /** Registrations whose boot handlers are still running. */
3880
+ this.inFlight = /* @__PURE__ */ new Set();
3881
+ }
3882
+ /**
3883
+ * Register a handler that is called whenever a new module is registered.
3884
+ */
3885
+ onModuleBoot(handler) {
3886
+ this.bootHandlers.push(handler);
3887
+ }
3888
+ /**
3889
+ * Register a web plugin module and notify all boot handlers.
3890
+ * Modules whose `apiVersion` is below the runtime's `API_VERSION` are
3891
+ * skipped with a warning — this ensures only compatible frontend plugins load.
3892
+ */
3893
+ register(module) {
3894
+ const registration = this.registerInternal(module);
3895
+ this.inFlight.add(registration);
3896
+ const done = () => this.inFlight.delete(registration);
3897
+ registration.then(done, done);
3898
+ return registration;
3899
+ }
3900
+ /**
3901
+ * Resolve once every registration in progress (including ones started
3902
+ * meanwhile, e.g. a plugin loading another) has finished booting.
3903
+ */
3904
+ async whenIdle() {
3905
+ while (this.inFlight.size > 0) {
3906
+ await Promise.allSettled([...this.inFlight]);
3907
+ }
3908
+ }
3909
+ async registerInternal(module) {
3910
+ const modApiVersion = module.apiVersion;
3911
+ if (typeof modApiVersion !== "number" || modApiVersion < API_VERSION) {
3912
+ const msg = `[CLI] Plugin "${module.name}" targets API version ${modApiVersion ?? "unknown"}, but this runtime requires API version ${API_VERSION}. Skipping.`;
3913
+ if (this.onWarn) {
3914
+ this.onWarn(msg);
3915
+ } else {
3916
+ console.warn(msg);
3917
+ }
3918
+ return;
3919
+ }
3920
+ this.modules.set(module.name, module);
3921
+ for (const handler of this.bootHandlers) {
3922
+ try {
3923
+ await handler(module);
3924
+ } catch (e) {
3925
+ const msg = `[CLI] Boot handler failed for module "${module.name}": ${e instanceof Error ? e.message : e}`;
3926
+ if (this.onWarn) {
3927
+ this.onWarn(msg);
3928
+ } else {
3929
+ console.warn(msg);
3930
+ }
3931
+ }
3932
+ }
3933
+ }
3934
+ /**
3935
+ * Register a handler that is called when a module is unregistered,
3936
+ * e.g. so its processors can be removed.
3937
+ */
3938
+ onModuleUnregister(handler) {
3939
+ this.unregisterHandlers.push(handler);
3940
+ }
3941
+ /**
3942
+ * Unregister a module and notify all unregister handlers. A module
3943
+ * registered again afterwards (e.g. a newer version) boots again.
3944
+ * Returns the removed module, or `undefined` when it was not registered.
3945
+ */
3946
+ unregister(name) {
3947
+ const module = this.modules.get(name);
3948
+ if (!module) return void 0;
3949
+ this.modules.delete(name);
3950
+ for (const handler of this.unregisterHandlers) {
3951
+ try {
3952
+ handler(module);
3953
+ } catch (e) {
3954
+ const msg = `[CLI] Unregister handler failed for module "${name}": ${e instanceof Error ? e.message : e}`;
3955
+ if (this.onWarn) {
3956
+ this.onWarn(msg);
3957
+ } else {
3958
+ console.warn(msg);
3959
+ }
3960
+ }
3961
+ }
3962
+ return module;
3963
+ }
3964
+ /**
3965
+ * Get a module by name.
3966
+ */
3967
+ getModule(name) {
3968
+ return this.modules.get(name);
3969
+ }
3970
+ /**
3971
+ * Get all registered modules.
3972
+ */
3973
+ getAll() {
3974
+ return Array.from(this.modules.values());
3975
+ }
3976
+ /**
3977
+ * Track a module without triggering boot handlers.
3978
+ * Used by the boot service for statically-provided modules that are
3979
+ * already being booted through the normal pipeline.
3980
+ */
3981
+ track(module) {
3982
+ this.modules.set(module.name, module);
3983
+ }
3984
+ /**
3985
+ * Check if a module is registered.
3986
+ */
3987
+ has(name) {
3988
+ return this.modules.has(name);
3989
+ }
3990
+ };
3991
+
3992
+ // src/lib/modules/index.ts
3993
+ var initializeBrowserEnvironment = ({
3994
+ context,
3995
+ registry
3996
+ }) => {
3997
+ window.__cliModuleRegistry = registry;
3998
+ window.cliCore = {
3999
+ ...constants,
4000
+ ...utils,
4001
+ ...enums,
4002
+ bootCliModule
4003
+ };
4004
+ Object.defineProperty(window, "ngCore", {
4005
+ configurable: true,
4006
+ get() {
4007
+ console.warn(
4008
+ "CLI: Angular decorators are not supported in UMD modules. Use plain classes instead."
4009
+ );
4010
+ return { Injectable: () => () => {
4011
+ } };
4012
+ }
4013
+ });
4014
+ };
4015
+ var bootCliModule = async (module) => {
4016
+ if (typeof window !== "undefined" && window.__cliModuleRegistry) {
4017
+ await window.__cliModuleRegistry.register(module);
4018
+ }
4019
+ };
4020
+
4021
+ // src/lib/types/CancellablePromise.ts
4022
+ var CANCELLATION_ERROR_MESSAGE = "Promise cancelled";
4023
+ var CancellablePromise = class {
4024
+ constructor(executor) {
4025
+ this.executor = executor;
4026
+ this.hasCancelled = false;
4027
+ this.abortController = new AbortController();
4028
+ }
4029
+ /**
4030
+ * Run the executor and return a promise for its result.
4031
+ * If `cancel()` has been called, the promise rejects immediately.
4032
+ */
4033
+ execute() {
4034
+ return new Promise((resolve, reject) => {
4035
+ this.abortController.signal.onabort = () => {
4036
+ reject(new Error(CANCELLATION_ERROR_MESSAGE));
4037
+ };
4038
+ this.executor(
4039
+ (value) => {
4040
+ if (!this.hasCancelled) {
4041
+ resolve(value);
4042
+ }
4043
+ },
4044
+ (reason) => {
4045
+ if (!this.hasCancelled) {
4046
+ reject(reason);
4047
+ }
4048
+ }
4049
+ );
4050
+ });
4051
+ }
4052
+ /**
4053
+ * Cancel the promise. The executing promise rejects with
4054
+ * `Error('Promise cancelled')` and subsequent resolve/reject calls are ignored.
4055
+ */
4056
+ cancel() {
4057
+ this.hasCancelled = true;
4058
+ this.abortController.abort();
4059
+ }
4060
+ };
3933
4061
 
3934
4062
  // src/lib/themes/default-theme-infos.ts
3935
4063
  var DefaultThemeInfos = {
@@ -3939,6 +4067,12 @@ var DefaultThemeInfos = {
3939
4067
  tags: ["built-in"],
3940
4068
  description: "Dark indigo theme with soft pastels"
3941
4069
  },
4070
+ light: {
4071
+ theme: DefaultThemes.light,
4072
+ category: "light",
4073
+ tags: ["built-in"],
4074
+ description: "Light counterpart of the default theme"
4075
+ },
3942
4076
  classic: {
3943
4077
  theme: DefaultThemes.classic,
3944
4078
  category: "dark",
@@ -4269,6 +4403,7 @@ exports.CliIcon = CliIcon;
4269
4403
  exports.CliKeyData = CliKeyData;
4270
4404
  exports.CliLogLevel = CliLogLevel;
4271
4405
  exports.CliModuleRegistry = CliModuleRegistry;
4406
+ exports.CliPanelPalettes = CliPanelPalettes;
4272
4407
  exports.CliServerPermissions = CliServerPermissions;
4273
4408
  exports.CliUsersPermissions = CliUsersPermissions;
4274
4409
  exports.DEFAULT_DIR_PERMISSIONS = DEFAULT_DIR_PERMISSIONS;
@@ -4319,12 +4454,14 @@ exports.cliRequireAuthGuard = cliRequireAuthGuard;
4319
4454
  exports.cliRequiredGroupsGuard = cliRequiredGroupsGuard;
4320
4455
  exports.cliRequiredPermissionsGuard = cliRequiredPermissionsGuard;
4321
4456
  exports.colorFirstWord = colorFirstWord;
4457
+ exports.colorSchemeOf = colorSchemeOf;
4322
4458
  exports.colorizeJson = colorizeJson;
4323
4459
  exports.compareVersions = compareVersions;
4324
4460
  exports.constants = constants;
4325
4461
  exports.createCliToken = createCliToken;
4326
4462
  exports.createWorkerService = createWorkerService;
4327
4463
  exports.delay = delay;
4464
+ exports.derivePanelColors = derivePanelColors;
4328
4465
  exports.derivePanelThemeStyles = derivePanelThemeStyles;
4329
4466
  exports.enums = enums;
4330
4467
  exports.formatJson = formatJson;
@@ -4338,9 +4475,12 @@ exports.isCliAccessDeniedError = isCliAccessDeniedError;
4338
4475
  exports.joinShellWords = joinShellWords;
4339
4476
  exports.loadPanelPosition = loadPanelPosition;
4340
4477
  exports.nextPanelPosition = nextPanelPosition;
4478
+ exports.panelColorStyles = panelColorStyles;
4479
+ exports.prefersDarkScheme = prefersDarkScheme;
4341
4480
  exports.quoteShellWord = quoteShellWord;
4342
4481
  exports.resolveConfigurationCategories = resolveConfigurationCategories;
4343
4482
  exports.resolveHeaders = resolveHeaders;
4483
+ exports.resolvePanelTheme = resolvePanelTheme;
4344
4484
  exports.resolveServerHeaders = resolveServerHeaders;
4345
4485
  exports.resolveServerWebSocketUrl = resolveServerWebSocketUrl;
4346
4486
  exports.satisfiesMinVersion = satisfiesMinVersion;