@qodalis/cli-core 2.1.0 → 2.2.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.0";
2602
+ var LIBRARY_VERSION = "2.2.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,29 @@ var DefaultThemes = {
3319
2749
  brightCyan: "#a5f3fc",
3320
2750
  brightWhite: "#f1f5f9"
3321
2751
  },
2752
+ light: {
2753
+ background: "#ffffff",
2754
+ foreground: "#1f2937",
2755
+ cursor: "#4f46e5",
2756
+ selectionBackground: "#c7d2fe",
2757
+ selectionForeground: "#111827",
2758
+ black: "#1f2937",
2759
+ red: "#dc2626",
2760
+ green: "#15803d",
2761
+ yellow: "#a16207",
2762
+ blue: "#4f46e5",
2763
+ magenta: "#9333ea",
2764
+ cyan: "#0e7490",
2765
+ white: "#6b7280",
2766
+ brightBlack: "#6b7280",
2767
+ brightRed: "#b91c1c",
2768
+ brightGreen: "#166534",
2769
+ brightYellow: "#854d0e",
2770
+ brightBlue: "#4338ca",
2771
+ brightMagenta: "#7e22ce",
2772
+ brightCyan: "#155e75",
2773
+ brightWhite: "#374151"
2774
+ },
3322
2775
  classic: {
3323
2776
  background: "#0c0c0c",
3324
2777
  foreground: "#cccccc",
@@ -3929,7 +3382,679 @@ var DefaultThemes = {
3929
3382
  brightWhite: "#ffffff"
3930
3383
  }
3931
3384
  };
3932
- DefaultThemes.yellow = DefaultThemes.highContrastLight;
3385
+ DefaultThemes.yellow = DefaultThemes.highContrastLight;
3386
+
3387
+ // src/lib/utils/panel-theme-sync.ts
3388
+ function hexToRgb(hex) {
3389
+ const short = /^#?([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f])$/.exec(hex);
3390
+ if (short) hex = short.slice(1).map((c) => c + c).join("");
3391
+ const m = /^#?([0-9A-Fa-f]{6})([0-9A-Fa-f]{2})?$/.exec(hex);
3392
+ if (!m) return null;
3393
+ const n = parseInt(m[1], 16);
3394
+ return { r: n >> 16 & 255, g: n >> 8 & 255, b: n & 255 };
3395
+ }
3396
+ function shiftColor(hex, amount) {
3397
+ const rgb = hexToRgb(hex);
3398
+ if (!rgb) return hex;
3399
+ const r = Math.min(255, Math.max(0, rgb.r + Math.round(amount)));
3400
+ const g = Math.min(255, Math.max(0, rgb.g + Math.round(amount)));
3401
+ const b = Math.min(255, Math.max(0, rgb.b + Math.round(amount)));
3402
+ return `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`;
3403
+ }
3404
+ function hexToRgba(hex, alpha) {
3405
+ const rgb = hexToRgb(hex);
3406
+ if (!rgb) return hex;
3407
+ return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${alpha})`;
3408
+ }
3409
+ function colorSchemeOf(color) {
3410
+ const rgb = color ? hexToRgb(color) : null;
3411
+ if (!rgb) return "dark";
3412
+ const channel = (v) => {
3413
+ const c = v / 255;
3414
+ return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
3415
+ };
3416
+ const luminance = 0.2126 * channel(rgb.r) + 0.7152 * channel(rgb.g) + 0.0722 * channel(rgb.b);
3417
+ return luminance > 0.4 ? "light" : "dark";
3418
+ }
3419
+ var CliPanelPalettes = Object.freeze({
3420
+ dark: Object.freeze({
3421
+ background: "#070b14",
3422
+ headerBackground: "#0f1623",
3423
+ border: "#1e293b",
3424
+ text: "#e2e8f0",
3425
+ textSecondary: "#94a3b8",
3426
+ accent: "#818cf8",
3427
+ hoverBackground: "rgba(129, 140, 248, 0.12)",
3428
+ activeBackground: "rgba(129, 140, 248, 0.22)",
3429
+ danger: "#f87171",
3430
+ shadow: "rgba(0, 0, 0, 0.45)"
3431
+ }),
3432
+ light: Object.freeze({
3433
+ background: "#ffffff",
3434
+ headerBackground: "#f8fafc",
3435
+ border: "#e2e8f0",
3436
+ text: "#0f172a",
3437
+ textSecondary: "#64748b",
3438
+ accent: "#4f46e5",
3439
+ hoverBackground: "rgba(79, 70, 229, 0.08)",
3440
+ activeBackground: "rgba(79, 70, 229, 0.14)",
3441
+ danger: "#dc2626",
3442
+ shadow: "rgba(15, 23, 42, 0.14)"
3443
+ })
3444
+ });
3445
+ var PALETTE_TERMINALS = {
3446
+ dark: DefaultThemes.default,
3447
+ light: DefaultThemes.light
3448
+ };
3449
+ function derivePanelColors(theme) {
3450
+ const scheme = colorSchemeOf(theme.background);
3451
+ const palette = CliPanelPalettes[scheme];
3452
+ const bg = theme.background || palette.background;
3453
+ const fg = theme.foreground || palette.text;
3454
+ const accent = theme.cyan || theme.blue || theme.magenta || palette.accent;
3455
+ const light = scheme === "light";
3456
+ return {
3457
+ background: bg,
3458
+ headerBackground: shiftColor(bg, light ? -8 : 12),
3459
+ border: shiftColor(bg, light ? -28 : 24),
3460
+ text: fg,
3461
+ textSecondary: hexToRgba(fg, 0.65),
3462
+ accent,
3463
+ hoverBackground: hexToRgba(accent, light ? 0.1 : 0.12),
3464
+ activeBackground: hexToRgba(accent, light ? 0.16 : 0.2),
3465
+ danger: theme.red || palette.danger,
3466
+ shadow: palette.shadow
3467
+ };
3468
+ }
3469
+ function panelColorStyles(colors) {
3470
+ return {
3471
+ "--cli-panel-bg": colors.background,
3472
+ "--cli-panel-header-bg": colors.headerBackground,
3473
+ "--cli-panel-border": colors.border,
3474
+ "--cli-panel-text": colors.text,
3475
+ "--cli-panel-text-secondary": colors.textSecondary,
3476
+ "--cli-panel-accent": colors.accent,
3477
+ "--cli-btn-hover-bg": colors.hoverBackground,
3478
+ "--cli-btn-active-bg": colors.activeBackground,
3479
+ "--cli-panel-danger": colors.danger,
3480
+ "--cli-panel-shadow": colors.shadow
3481
+ };
3482
+ }
3483
+ function derivePanelThemeStyles(theme) {
3484
+ return {
3485
+ ...panelColorStyles(derivePanelColors(theme)),
3486
+ "color-scheme": colorSchemeOf(theme.background)
3487
+ };
3488
+ }
3489
+ function resolvePanelTheme(input, prefersDark, themes = DefaultThemes) {
3490
+ const pick = (scheme2) => scheme2 === "auto" ? prefersDark ? "dark" : "light" : scheme2;
3491
+ const lookup = (name) => themes[name];
3492
+ let scheme;
3493
+ let terminal;
3494
+ let colors;
3495
+ let font;
3496
+ let radius;
3497
+ if (input === void 0 || input === "dark" || input === "light" || input === "auto") {
3498
+ scheme = pick(input ?? "dark");
3499
+ terminal = PALETTE_TERMINALS[scheme];
3500
+ colors = { ...CliPanelPalettes[scheme] };
3501
+ } else if (typeof input === "string") {
3502
+ const named = lookup(input);
3503
+ terminal = named ?? PALETTE_TERMINALS.dark;
3504
+ scheme = colorSchemeOf(terminal.background);
3505
+ colors = named ? derivePanelColors(named) : { ...CliPanelPalettes.dark };
3506
+ } else {
3507
+ const custom = typeof input.terminal === "string" ? lookup(input.terminal) : input.terminal;
3508
+ scheme = input.base ? pick(input.base) : custom ? colorSchemeOf(custom.background) : "dark";
3509
+ terminal = custom ?? PALETTE_TERMINALS[scheme];
3510
+ colors = custom ? derivePanelColors(custom) : { ...CliPanelPalettes[scheme] };
3511
+ if (input.colors) colors = { ...colors, ...stripUndefined(input.colors) };
3512
+ font = input.fontFamily;
3513
+ radius = input.radius;
3514
+ }
3515
+ const styles = { ...panelColorStyles(colors), "color-scheme": scheme };
3516
+ if (font) styles["--cli-panel-font"] = font;
3517
+ if (radius) styles["--cli-panel-radius"] = radius;
3518
+ return { scheme, styles, terminal };
3519
+ }
3520
+ function stripUndefined(value) {
3521
+ return Object.fromEntries(Object.entries(value).filter(([, v]) => v !== void 0));
3522
+ }
3523
+ function prefersDarkScheme() {
3524
+ if (typeof window === "undefined" || !window.matchMedia) return true;
3525
+ return window.matchMedia("(prefers-color-scheme: dark)").matches;
3526
+ }
3527
+
3528
+ // src/lib/utils/panel-position-store.ts
3529
+ var STORAGE_KEY = "cli-panel-position";
3530
+ var POSITION_CYCLE = ["bottom", "right", "top", "left"];
3531
+ function loadPanelPosition() {
3532
+ try {
3533
+ const stored = localStorage.getItem(STORAGE_KEY);
3534
+ if (stored && POSITION_CYCLE.includes(stored)) {
3535
+ return stored;
3536
+ }
3537
+ } catch {
3538
+ }
3539
+ return null;
3540
+ }
3541
+ function savePanelPosition(position) {
3542
+ try {
3543
+ localStorage.setItem(STORAGE_KEY, position);
3544
+ } catch {
3545
+ }
3546
+ }
3547
+ function nextPanelPosition(current) {
3548
+ const index = POSITION_CYCLE.indexOf(current);
3549
+ if (index === -1) {
3550
+ return POSITION_CYCLE[0];
3551
+ }
3552
+ return POSITION_CYCLE[(index + 1) % POSITION_CYCLE.length];
3553
+ }
3554
+
3555
+ // src/lib/utils/ansi-utils.ts
3556
+ var ANSI_RE = /\x1b\[[0-9;]*m/g;
3557
+ function stripAnsi(text) {
3558
+ return text.replace(ANSI_RE, "");
3559
+ }
3560
+ function visibleLength(text) {
3561
+ const stripped = stripAnsi(text);
3562
+ let width = 0;
3563
+ for (const ch of stripped) {
3564
+ const cp = ch.codePointAt(0);
3565
+ if (cp >= 65024 && cp <= 65039) continue;
3566
+ if (cp === 8205) continue;
3567
+ if (cp >= 768 && cp <= 879) continue;
3568
+ width += isWideCharacter(cp) ? 2 : 1;
3569
+ }
3570
+ return width;
3571
+ }
3572
+ function truncateToWidth(text, width, ellipsis = "\u2026") {
3573
+ if (width < 1) return "";
3574
+ if (visibleLength(text) <= width) return text;
3575
+ const room = Math.max(0, width - visibleLength(ellipsis));
3576
+ let out = "";
3577
+ let used = 0;
3578
+ let i = 0;
3579
+ while (i < text.length) {
3580
+ if (text[i] === "\x1B") {
3581
+ const m = /^\x1b\[[0-9;]*m/.exec(text.slice(i));
3582
+ if (m) {
3583
+ out += m[0];
3584
+ i += m[0].length;
3585
+ continue;
3586
+ }
3587
+ }
3588
+ const ch = String.fromCodePoint(text.codePointAt(i));
3589
+ const w = visibleLength(ch);
3590
+ if (used + w > room) break;
3591
+ out += ch;
3592
+ used += w;
3593
+ i += ch.length;
3594
+ }
3595
+ return `${out}${ellipsis}\x1B[0m`;
3596
+ }
3597
+ function isWideCharacter(cp) {
3598
+ if (cp >= 126976) return true;
3599
+ if (cp >= 9728 && cp <= 10175) return true;
3600
+ if (cp >= 9984 && cp <= 10175) return true;
3601
+ if (cp >= 19968 && cp <= 40959) return true;
3602
+ if (cp >= 63744 && cp <= 64255) return true;
3603
+ if (cp >= 65281 && cp <= 65376) return true;
3604
+ if (cp >= 65504 && cp <= 65510) return true;
3605
+ if (cp >= 11904 && cp <= 12255) return true;
3606
+ if (cp >= 12288 && cp <= 12543) return true;
3607
+ if (cp >= 12800 && cp <= 13055) return true;
3608
+ if (cp >= 13056 && cp <= 13311) return true;
3609
+ if (cp >= 127232 && cp <= 127487) return true;
3610
+ if (cp >= 8960 && cp <= 9215) return true;
3611
+ return false;
3612
+ }
3613
+
3614
+ // src/lib/utils/access-guards.ts
3615
+ var list = (value) => Array.isArray(value) ? value.filter((v) => typeof v === "string" && v.trim()) : [];
3616
+ var authorization = (context) => {
3617
+ try {
3618
+ return context.services.get(ICliAuthorizationService_TOKEN);
3619
+ } catch {
3620
+ return void 0;
3621
+ }
3622
+ };
3623
+ function chain(processor) {
3624
+ const out = [];
3625
+ let current = processor;
3626
+ while (current && out.length < 32 && !out.includes(current)) {
3627
+ out.push(current);
3628
+ current = current.parent;
3629
+ }
3630
+ return out;
3631
+ }
3632
+ var requiredPermissionsOf = (p) => [...new Set(chain(p).flatMap((x) => list(x.metadata?.requiredPermissions)))];
3633
+ var requiredGroupLevels = (p) => chain(p).map((x) => list(x.metadata?.requiredGroups)).filter((g) => g.length > 0);
3634
+ var needsAuth = (p) => chain(p).some((x) => x.metadata?.requireAuth === true) || requiredGroupLevels(p).length > 0 || requiredPermissionsOf(p).length > 0;
3635
+ var cliRequireAuthGuard = {
3636
+ name: "access:require-auth",
3637
+ priority: -100,
3638
+ appliesTo: (processor, _command, context) => needsAuth(processor) && !!authorization(context),
3639
+ canActivate: (_command, processor, context) => authorization(context).getPrincipal() ? true : `${processor.command}: login required`
3640
+ };
3641
+ var cliRequiredGroupsGuard = {
3642
+ name: "access:required-groups",
3643
+ priority: -90,
3644
+ appliesTo: (processor, _command, context) => requiredGroupLevels(processor).length > 0 && !!authorization(context),
3645
+ canActivate: (_command, processor, context) => {
3646
+ const auth = authorization(context);
3647
+ const principal = auth.getPrincipal();
3648
+ if (!principal) return `${processor.command}: login required`;
3649
+ if (auth.can("*")) return true;
3650
+ for (const required of requiredGroupLevels(processor)) {
3651
+ const member = required.some((g) => principal.groups.some((pg) => pg.toLowerCase() === g.toLowerCase()));
3652
+ if (!member) return `${processor.command}: permission denied (requires group: ${required.join(" or ")})`;
3653
+ }
3654
+ return true;
3655
+ }
3656
+ };
3657
+ var cliRequiredPermissionsGuard = {
3658
+ name: "access:required-permissions",
3659
+ priority: -80,
3660
+ appliesTo: (processor, _command, context) => requiredPermissionsOf(processor).length > 0 && !!authorization(context),
3661
+ canActivate: (_command, processor, context) => {
3662
+ const principal = authorization(context).getPrincipal();
3663
+ if (!principal) return `${processor.command}: login required`;
3664
+ const missing = cliMissingPermissions(principal.permissions, requiredPermissionsOf(processor));
3665
+ return missing.length === 0 ? true : `${processor.command}: permission denied (requires ${missing.join(", ")})`;
3666
+ }
3667
+ };
3668
+ var cliAccessMetadataGuards = [
3669
+ cliRequireAuthGuard,
3670
+ cliRequiredGroupsGuard,
3671
+ cliRequiredPermissionsGuard
3672
+ ];
3673
+
3674
+ // src/lib/utils/server-target.ts
3675
+ function cliDefaultServer(context) {
3676
+ const servers = context.options?.servers ?? [];
3677
+ const manager = context.services?.get(ICliServerManager_TOKEN);
3678
+ const preferred = manager?.preferredServer?.();
3679
+ return (preferred ? servers.find((s) => s.name === preferred) : void 0) ?? servers[0];
3680
+ }
3681
+
3682
+ // src/lib/utils/help-format.ts
3683
+ function writeColumns(context, rows, formatLeft, formatRight) {
3684
+ const width = Math.max(...rows.map(([left]) => left.length)) + 2;
3685
+ for (const [left, right] of rows) {
3686
+ context.writer.writeln(
3687
+ ` ${formatLeft(left.padEnd(width))}${formatRight(right)}`
3688
+ );
3689
+ }
3690
+ }
3691
+ function writeUsage(context, rows) {
3692
+ const { writer, translator } = context;
3693
+ writer.writeln(`\u{1F4CB} ${translator.t("cli.common.usage", "Usage:")}`);
3694
+ writeColumns(
3695
+ context,
3696
+ rows,
3697
+ (cmd) => writer.wrapInColor(cmd, "\x1B[36m" /* Cyan */),
3698
+ (text) => text
3699
+ );
3700
+ }
3701
+ function writeExamples(context, rows) {
3702
+ const { writer, translator } = context;
3703
+ writer.writeln(`\u{1F4DD} ${translator.t("cli.common.examples", "Examples:")}`);
3704
+ writeColumns(
3705
+ context,
3706
+ rows,
3707
+ (cmd) => cmd,
3708
+ (comment) => writer.wrapInColor(`# ${comment}`, "\x1B[32m" /* Green */)
3709
+ );
3710
+ }
3711
+ function writeWrapped(context, text, indent = 0) {
3712
+ const cols = context.terminal?.cols ?? 80;
3713
+ const width = Math.max(20, Math.min(cols - 1, 100) - indent);
3714
+ const pad = " ".repeat(indent);
3715
+ let line = "";
3716
+ for (const word of text.split(/\s+/).filter(Boolean)) {
3717
+ if (line && visibleLength2(line) + 1 + visibleLength2(word) > width) {
3718
+ context.writer.writeln(pad + line);
3719
+ line = word;
3720
+ } else {
3721
+ line = line ? `${line} ${word}` : word;
3722
+ }
3723
+ }
3724
+ if (line) context.writer.writeln(pad + line);
3725
+ }
3726
+ function visibleLength2(text) {
3727
+ return text.replace(/\x1b\[[0-9;]*m/g, "").length;
3728
+ }
3729
+ function writeHint(context, command, action) {
3730
+ const { writer, translator } = context;
3731
+ const text = `\u{1F4A1} ${translator.t("cli.common.use_hint", "Use {command} {action}", {
3732
+ command: writer.wrapInColor(command, "\x1B[36m" /* Cyan */),
3733
+ action
3734
+ })}`;
3735
+ const width = Math.min((context.terminal?.cols ?? 80) - 1, 100) - 3;
3736
+ if (visibleLength2(text) + 1 <= width) {
3737
+ writer.writeInfo(text);
3738
+ return;
3739
+ }
3740
+ const lines = [];
3741
+ let line = "";
3742
+ for (const word of text.split(" ")) {
3743
+ if (line && visibleLength2(line) + 1 + visibleLength2(word) > width) {
3744
+ lines.push(line);
3745
+ line = word;
3746
+ } else {
3747
+ line = line ? `${line} ${word}` : word;
3748
+ }
3749
+ }
3750
+ if (line) lines.push(line);
3751
+ writer.writeInfo(lines[0]);
3752
+ for (const rest of lines.slice(1)) {
3753
+ writer.writeln(` ${rest}`);
3754
+ }
3755
+ }
3756
+
3757
+ // src/lib/utils/raw-argument.ts
3758
+ function unquoteRawArgument(text) {
3759
+ const value = text.trim();
3760
+ if (value.length < 2) return value;
3761
+ const quote = value[0];
3762
+ if (quote === "'") {
3763
+ return value.indexOf("'", 1) === value.length - 1 ? value.slice(1, -1) : value;
3764
+ }
3765
+ if (quote === '"') {
3766
+ for (let i = 1; i < value.length; i++) {
3767
+ if (value[i] === "\\") i++;
3768
+ else if (value[i] === '"') {
3769
+ return i === value.length - 1 ? value.slice(1, -1).replace(/\\(["\\$`])/g, "$1") : value;
3770
+ }
3771
+ }
3772
+ }
3773
+ return value;
3774
+ }
3775
+
3776
+ // src/lib/utils/index.ts
3777
+ var getParameterValue = (p, args) => {
3778
+ if (args[p.name] !== void 0) {
3779
+ return args[p.name];
3780
+ }
3781
+ const matchedAlias = p.aliases?.find((alias) => args[alias] !== void 0);
3782
+ return matchedAlias ? args[matchedAlias] : void 0;
3783
+ };
3784
+ var formatJson = (json) => {
3785
+ const identedJson = JSON.stringify(json, null, 2);
3786
+ return colorizeJson(identedJson.split("\n").join("\r\n"));
3787
+ };
3788
+ var colorizeJson = (jsonString) => {
3789
+ const RST = "\x1B[0m";
3790
+ const CYN = "\x1B[36m";
3791
+ const GRN = "\x1B[32m";
3792
+ const YLW = "\x1B[33m";
3793
+ const GRY = "\x1B[90m";
3794
+ const tokenRe = /("(?:[^"\\]|\\.)*"?)(\s*:)?|(\btrue\b|\bfalse\b|\bnull\b)|(-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)|([{}[\],])/g;
3795
+ let result = "";
3796
+ let lastIndex = 0;
3797
+ let m;
3798
+ while ((m = tokenRe.exec(jsonString)) !== null) {
3799
+ if (m.index > lastIndex) {
3800
+ result += jsonString.slice(lastIndex, m.index);
3801
+ }
3802
+ if (m[1] !== void 0) {
3803
+ if (m[2] !== void 0) {
3804
+ result += CYN + m[1] + RST + m[2];
3805
+ } else {
3806
+ result += GRN + m[1] + RST;
3807
+ }
3808
+ } else if (m[3] !== void 0) {
3809
+ result += YLW + m[3] + RST;
3810
+ } else if (m[4] !== void 0) {
3811
+ result += YLW + m[4] + RST;
3812
+ } else if (m[5] !== void 0) {
3813
+ result += GRY + m[5] + RST;
3814
+ }
3815
+ lastIndex = m.index + m[0].length;
3816
+ }
3817
+ if (lastIndex < jsonString.length) {
3818
+ result += jsonString.slice(lastIndex);
3819
+ }
3820
+ return result;
3821
+ };
3822
+ var toQueryString = (params) => {
3823
+ const searchParams = new URLSearchParams();
3824
+ for (const [key, value] of Object.entries(params)) {
3825
+ if (Array.isArray(value)) {
3826
+ value.forEach((v) => searchParams.append(key, v.toString()));
3827
+ } else if (value !== null && value !== void 0) {
3828
+ searchParams.append(key, value.toString());
3829
+ }
3830
+ }
3831
+ return searchParams.toString();
3832
+ };
3833
+ var highlightTextWithBg = (text, pattern, bgColor = "\x1B[43m" /* Yellow */) => {
3834
+ return text.replace(
3835
+ pattern,
3836
+ (match) => `${bgColor}${match}${"\x1B[0m" /* Reset */}`
3837
+ );
3838
+ };
3839
+ var getRightOfWord = (command, word) => {
3840
+ const index = command.indexOf(word);
3841
+ if (index !== -1) {
3842
+ return command.slice(index + word.length).trim();
3843
+ }
3844
+ return void 0;
3845
+ };
3846
+ var colorFirstWord = (text, colorFunction) => {
3847
+ if (!text) return text;
3848
+ const match = text.match(/^(\s*)(\S+)(.*)$/);
3849
+ if (!match) return text;
3850
+ const [, leadingSpaces, firstWord, restOfText] = match;
3851
+ const firstWordColored = colorFunction(firstWord);
3852
+ return `${leadingSpaces}${firstWordColored}${restOfText}`;
3853
+ };
3854
+ var utils = {
3855
+ getParameterValue,
3856
+ formatJson,
3857
+ colorizeJson,
3858
+ toQueryString,
3859
+ highlightTextWithBg,
3860
+ getRightOfWord,
3861
+ colorFirstWord,
3862
+ ObjectDescriber,
3863
+ delay,
3864
+ getConfigValue,
3865
+ getPluginConfigValue,
3866
+ resolveConfigurationCategories,
3867
+ CLI_CONFIGURE_STORE_NAME
3868
+ };
3869
+
3870
+ // src/lib/modules/cli-module-registry.ts
3871
+ var CliModuleRegistry = class {
3872
+ constructor() {
3873
+ this.modules = /* @__PURE__ */ new Map();
3874
+ this.bootHandlers = [];
3875
+ this.unregisterHandlers = [];
3876
+ /** Registrations whose boot handlers are still running. */
3877
+ this.inFlight = /* @__PURE__ */ new Set();
3878
+ }
3879
+ /**
3880
+ * Register a handler that is called whenever a new module is registered.
3881
+ */
3882
+ onModuleBoot(handler) {
3883
+ this.bootHandlers.push(handler);
3884
+ }
3885
+ /**
3886
+ * Register a web plugin module and notify all boot handlers.
3887
+ * Modules whose `apiVersion` is below the runtime's `API_VERSION` are
3888
+ * skipped with a warning — this ensures only compatible frontend plugins load.
3889
+ */
3890
+ register(module) {
3891
+ const registration = this.registerInternal(module);
3892
+ this.inFlight.add(registration);
3893
+ const done = () => this.inFlight.delete(registration);
3894
+ registration.then(done, done);
3895
+ return registration;
3896
+ }
3897
+ /**
3898
+ * Resolve once every registration in progress (including ones started
3899
+ * meanwhile, e.g. a plugin loading another) has finished booting.
3900
+ */
3901
+ async whenIdle() {
3902
+ while (this.inFlight.size > 0) {
3903
+ await Promise.allSettled([...this.inFlight]);
3904
+ }
3905
+ }
3906
+ async registerInternal(module) {
3907
+ const modApiVersion = module.apiVersion;
3908
+ if (typeof modApiVersion !== "number" || modApiVersion < API_VERSION) {
3909
+ const msg = `[CLI] Plugin "${module.name}" targets API version ${modApiVersion ?? "unknown"}, but this runtime requires API version ${API_VERSION}. Skipping.`;
3910
+ if (this.onWarn) {
3911
+ this.onWarn(msg);
3912
+ } else {
3913
+ console.warn(msg);
3914
+ }
3915
+ return;
3916
+ }
3917
+ this.modules.set(module.name, module);
3918
+ for (const handler of this.bootHandlers) {
3919
+ try {
3920
+ await handler(module);
3921
+ } catch (e) {
3922
+ const msg = `[CLI] Boot handler failed for module "${module.name}": ${e instanceof Error ? e.message : e}`;
3923
+ if (this.onWarn) {
3924
+ this.onWarn(msg);
3925
+ } else {
3926
+ console.warn(msg);
3927
+ }
3928
+ }
3929
+ }
3930
+ }
3931
+ /**
3932
+ * Register a handler that is called when a module is unregistered,
3933
+ * e.g. so its processors can be removed.
3934
+ */
3935
+ onModuleUnregister(handler) {
3936
+ this.unregisterHandlers.push(handler);
3937
+ }
3938
+ /**
3939
+ * Unregister a module and notify all unregister handlers. A module
3940
+ * registered again afterwards (e.g. a newer version) boots again.
3941
+ * Returns the removed module, or `undefined` when it was not registered.
3942
+ */
3943
+ unregister(name) {
3944
+ const module = this.modules.get(name);
3945
+ if (!module) return void 0;
3946
+ this.modules.delete(name);
3947
+ for (const handler of this.unregisterHandlers) {
3948
+ try {
3949
+ handler(module);
3950
+ } catch (e) {
3951
+ const msg = `[CLI] Unregister handler failed for module "${name}": ${e instanceof Error ? e.message : e}`;
3952
+ if (this.onWarn) {
3953
+ this.onWarn(msg);
3954
+ } else {
3955
+ console.warn(msg);
3956
+ }
3957
+ }
3958
+ }
3959
+ return module;
3960
+ }
3961
+ /**
3962
+ * Get a module by name.
3963
+ */
3964
+ getModule(name) {
3965
+ return this.modules.get(name);
3966
+ }
3967
+ /**
3968
+ * Get all registered modules.
3969
+ */
3970
+ getAll() {
3971
+ return Array.from(this.modules.values());
3972
+ }
3973
+ /**
3974
+ * Track a module without triggering boot handlers.
3975
+ * Used by the boot service for statically-provided modules that are
3976
+ * already being booted through the normal pipeline.
3977
+ */
3978
+ track(module) {
3979
+ this.modules.set(module.name, module);
3980
+ }
3981
+ /**
3982
+ * Check if a module is registered.
3983
+ */
3984
+ has(name) {
3985
+ return this.modules.has(name);
3986
+ }
3987
+ };
3988
+
3989
+ // src/lib/modules/index.ts
3990
+ var initializeBrowserEnvironment = ({
3991
+ context,
3992
+ registry
3993
+ }) => {
3994
+ window.__cliModuleRegistry = registry;
3995
+ window.cliCore = {
3996
+ ...constants,
3997
+ ...utils,
3998
+ ...enums,
3999
+ bootCliModule
4000
+ };
4001
+ Object.defineProperty(window, "ngCore", {
4002
+ configurable: true,
4003
+ get() {
4004
+ console.warn(
4005
+ "CLI: Angular decorators are not supported in UMD modules. Use plain classes instead."
4006
+ );
4007
+ return { Injectable: () => () => {
4008
+ } };
4009
+ }
4010
+ });
4011
+ };
4012
+ var bootCliModule = async (module) => {
4013
+ if (typeof window !== "undefined" && window.__cliModuleRegistry) {
4014
+ await window.__cliModuleRegistry.register(module);
4015
+ }
4016
+ };
4017
+
4018
+ // src/lib/types/CancellablePromise.ts
4019
+ var CANCELLATION_ERROR_MESSAGE = "Promise cancelled";
4020
+ var CancellablePromise = class {
4021
+ constructor(executor) {
4022
+ this.executor = executor;
4023
+ this.hasCancelled = false;
4024
+ this.abortController = new AbortController();
4025
+ }
4026
+ /**
4027
+ * Run the executor and return a promise for its result.
4028
+ * If `cancel()` has been called, the promise rejects immediately.
4029
+ */
4030
+ execute() {
4031
+ return new Promise((resolve, reject) => {
4032
+ this.abortController.signal.onabort = () => {
4033
+ reject(new Error(CANCELLATION_ERROR_MESSAGE));
4034
+ };
4035
+ this.executor(
4036
+ (value) => {
4037
+ if (!this.hasCancelled) {
4038
+ resolve(value);
4039
+ }
4040
+ },
4041
+ (reason) => {
4042
+ if (!this.hasCancelled) {
4043
+ reject(reason);
4044
+ }
4045
+ }
4046
+ );
4047
+ });
4048
+ }
4049
+ /**
4050
+ * Cancel the promise. The executing promise rejects with
4051
+ * `Error('Promise cancelled')` and subsequent resolve/reject calls are ignored.
4052
+ */
4053
+ cancel() {
4054
+ this.hasCancelled = true;
4055
+ this.abortController.abort();
4056
+ }
4057
+ };
3933
4058
 
3934
4059
  // src/lib/themes/default-theme-infos.ts
3935
4060
  var DefaultThemeInfos = {
@@ -3939,6 +4064,12 @@ var DefaultThemeInfos = {
3939
4064
  tags: ["built-in"],
3940
4065
  description: "Dark indigo theme with soft pastels"
3941
4066
  },
4067
+ light: {
4068
+ theme: DefaultThemes.light,
4069
+ category: "light",
4070
+ tags: ["built-in"],
4071
+ description: "Light counterpart of the default theme"
4072
+ },
3942
4073
  classic: {
3943
4074
  theme: DefaultThemes.classic,
3944
4075
  category: "dark",
@@ -4269,6 +4400,7 @@ exports.CliIcon = CliIcon;
4269
4400
  exports.CliKeyData = CliKeyData;
4270
4401
  exports.CliLogLevel = CliLogLevel;
4271
4402
  exports.CliModuleRegistry = CliModuleRegistry;
4403
+ exports.CliPanelPalettes = CliPanelPalettes;
4272
4404
  exports.CliServerPermissions = CliServerPermissions;
4273
4405
  exports.CliUsersPermissions = CliUsersPermissions;
4274
4406
  exports.DEFAULT_DIR_PERMISSIONS = DEFAULT_DIR_PERMISSIONS;
@@ -4319,12 +4451,14 @@ exports.cliRequireAuthGuard = cliRequireAuthGuard;
4319
4451
  exports.cliRequiredGroupsGuard = cliRequiredGroupsGuard;
4320
4452
  exports.cliRequiredPermissionsGuard = cliRequiredPermissionsGuard;
4321
4453
  exports.colorFirstWord = colorFirstWord;
4454
+ exports.colorSchemeOf = colorSchemeOf;
4322
4455
  exports.colorizeJson = colorizeJson;
4323
4456
  exports.compareVersions = compareVersions;
4324
4457
  exports.constants = constants;
4325
4458
  exports.createCliToken = createCliToken;
4326
4459
  exports.createWorkerService = createWorkerService;
4327
4460
  exports.delay = delay;
4461
+ exports.derivePanelColors = derivePanelColors;
4328
4462
  exports.derivePanelThemeStyles = derivePanelThemeStyles;
4329
4463
  exports.enums = enums;
4330
4464
  exports.formatJson = formatJson;
@@ -4338,9 +4472,12 @@ exports.isCliAccessDeniedError = isCliAccessDeniedError;
4338
4472
  exports.joinShellWords = joinShellWords;
4339
4473
  exports.loadPanelPosition = loadPanelPosition;
4340
4474
  exports.nextPanelPosition = nextPanelPosition;
4475
+ exports.panelColorStyles = panelColorStyles;
4476
+ exports.prefersDarkScheme = prefersDarkScheme;
4341
4477
  exports.quoteShellWord = quoteShellWord;
4342
4478
  exports.resolveConfigurationCategories = resolveConfigurationCategories;
4343
4479
  exports.resolveHeaders = resolveHeaders;
4480
+ exports.resolvePanelTheme = resolvePanelTheme;
4344
4481
  exports.resolveServerHeaders = resolveServerHeaders;
4345
4482
  exports.resolveServerWebSocketUrl = resolveServerWebSocketUrl;
4346
4483
  exports.satisfiesMinVersion = satisfiesMinVersion;