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