@qodalis/cli 2.2.0 → 2.4.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/assets/cli-panel.css +127 -64
- package/package.json +2 -2
- package/public-api.d.mts +13 -9
- package/public-api.d.ts +13 -9
- package/public-api.js +278 -137
- package/public-api.js.map +1 -1
- package/public-api.mjs +278 -137
- package/public-api.mjs.map +1 -1
package/public-api.js
CHANGED
|
@@ -519,7 +519,7 @@ var CliKeyValueStore_TOKEN = cliCore.createCliToken("cli-key-value-store");
|
|
|
519
519
|
var SyntaxHighlighterRegistry_TOKEN = cliCore.createCliToken("syntax-highlighter-registry");
|
|
520
520
|
|
|
521
521
|
// src/lib/version.ts
|
|
522
|
-
var LIBRARY_VERSION = "2.
|
|
522
|
+
var LIBRARY_VERSION = "2.4.0";
|
|
523
523
|
var API_VERSION = 2;
|
|
524
524
|
var ANONYMOUS = "\0anonymous";
|
|
525
525
|
function aliasOwner(context2) {
|
|
@@ -11188,7 +11188,78 @@ var CliServicesCommandProcessor = class {
|
|
|
11188
11188
|
);
|
|
11189
11189
|
}
|
|
11190
11190
|
};
|
|
11191
|
+
var CLI_EVENT_HISTORY_SIZE = 200;
|
|
11192
|
+
function matchesEventPattern(type, pattern) {
|
|
11193
|
+
if (pattern === "*") return true;
|
|
11194
|
+
if (pattern.endsWith(":*")) {
|
|
11195
|
+
return type.startsWith(pattern.slice(0, -1));
|
|
11196
|
+
}
|
|
11197
|
+
return type === pattern;
|
|
11198
|
+
}
|
|
11199
|
+
var CliEventBus = class {
|
|
11200
|
+
constructor(onHandlerError = (error) => console.error("[CLI] Event handler failed:", error), historySize = CLI_EVENT_HISTORY_SIZE) {
|
|
11201
|
+
this.onHandlerError = onHandlerError;
|
|
11202
|
+
this.historySize = historySize;
|
|
11203
|
+
this.subject = new rxjs.Subject();
|
|
11204
|
+
this.recent = [];
|
|
11205
|
+
this.disposed = false;
|
|
11206
|
+
}
|
|
11207
|
+
emit(type, data, options) {
|
|
11208
|
+
if (this.disposed) return;
|
|
11209
|
+
const event = {
|
|
11210
|
+
type,
|
|
11211
|
+
data,
|
|
11212
|
+
source: options?.source,
|
|
11213
|
+
timestamp: Date.now()
|
|
11214
|
+
};
|
|
11215
|
+
this.recent.push(event);
|
|
11216
|
+
if (this.recent.length > this.historySize) {
|
|
11217
|
+
this.recent.shift();
|
|
11218
|
+
}
|
|
11219
|
+
this.subject.next(event);
|
|
11220
|
+
}
|
|
11221
|
+
on(pattern, handler) {
|
|
11222
|
+
const subscription = this.events$(pattern).subscribe((event) => {
|
|
11223
|
+
try {
|
|
11224
|
+
handler(event);
|
|
11225
|
+
} catch (error) {
|
|
11226
|
+
this.onHandlerError(error, event);
|
|
11227
|
+
}
|
|
11228
|
+
});
|
|
11229
|
+
return () => subscription.unsubscribe();
|
|
11230
|
+
}
|
|
11231
|
+
once(pattern, handler) {
|
|
11232
|
+
let done = false;
|
|
11233
|
+
const unsubscribe = this.on(pattern, (event) => {
|
|
11234
|
+
if (done) return;
|
|
11235
|
+
done = true;
|
|
11236
|
+
unsubscribe();
|
|
11237
|
+
handler(event);
|
|
11238
|
+
});
|
|
11239
|
+
return unsubscribe;
|
|
11240
|
+
}
|
|
11241
|
+
events$(pattern = "*") {
|
|
11242
|
+
return this.subject.asObservable().pipe(operators.filter((event) => matchesEventPattern(event.type, pattern)));
|
|
11243
|
+
}
|
|
11244
|
+
history(pattern = "*", limit) {
|
|
11245
|
+
const matching = this.recent.filter(
|
|
11246
|
+
(event) => matchesEventPattern(event.type, pattern)
|
|
11247
|
+
);
|
|
11248
|
+
return limit !== void 0 ? matching.slice(-limit) : matching;
|
|
11249
|
+
}
|
|
11250
|
+
/** Stop delivering events and complete all observables. */
|
|
11251
|
+
dispose() {
|
|
11252
|
+
if (this.disposed) return;
|
|
11253
|
+
this.disposed = true;
|
|
11254
|
+
this.subject.complete();
|
|
11255
|
+
this.recent.length = 0;
|
|
11256
|
+
}
|
|
11257
|
+
};
|
|
11258
|
+
|
|
11259
|
+
// src/lib/processors/system/cli-events-command-processor.ts
|
|
11191
11260
|
var DATA_PREVIEW_LENGTH = 120;
|
|
11261
|
+
var SERVER_EVENT = "server:event";
|
|
11262
|
+
var SERVER_ENVELOPE_FIELDS = /* @__PURE__ */ new Set(["type", "timestamp"]);
|
|
11192
11263
|
var RESERVED_NAMESPACES = [
|
|
11193
11264
|
"boot",
|
|
11194
11265
|
"command",
|
|
@@ -11200,26 +11271,83 @@ var RESERVED_NAMESPACES = [
|
|
|
11200
11271
|
"session",
|
|
11201
11272
|
"user"
|
|
11202
11273
|
];
|
|
11274
|
+
function serverEventOf(event) {
|
|
11275
|
+
return event.type === SERVER_EVENT ? event.data : void 0;
|
|
11276
|
+
}
|
|
11277
|
+
function matchesFilter(event, filter2) {
|
|
11278
|
+
const remote = serverEventOf(event);
|
|
11279
|
+
if (!remote) {
|
|
11280
|
+
return !filter2.server && matchesEventPattern(event.type, filter2.pattern);
|
|
11281
|
+
}
|
|
11282
|
+
if (filter2.local) return false;
|
|
11283
|
+
if (filter2.server && remote.server.toLowerCase() !== filter2.server.toLowerCase()) return false;
|
|
11284
|
+
return matchesEventPattern(remote.type, filter2.pattern) || matchesEventPattern(SERVER_EVENT, filter2.pattern);
|
|
11285
|
+
}
|
|
11203
11286
|
function canSee(event, context2) {
|
|
11204
11287
|
return !event.type.startsWith("user:") || cliCore.cliAuthorize(context2, cliCore.CliUsersPermissions.AuditRead);
|
|
11205
11288
|
}
|
|
11289
|
+
function formatServerEventFields(data) {
|
|
11290
|
+
if (!data || typeof data !== "object") return "";
|
|
11291
|
+
const parts = [];
|
|
11292
|
+
for (const [key, value] of Object.entries(data)) {
|
|
11293
|
+
if (SERVER_ENVELOPE_FIELDS.has(key) || value === void 0 || value === null) continue;
|
|
11294
|
+
const text = typeof value === "string" ? value : JSON.stringify(value);
|
|
11295
|
+
parts.push(`${key}=${/\s/.test(text) ? JSON.stringify(text) : text}`);
|
|
11296
|
+
}
|
|
11297
|
+
return shorten(parts.join(" "));
|
|
11298
|
+
}
|
|
11299
|
+
function shorten(text) {
|
|
11300
|
+
return text.length > DATA_PREVIEW_LENGTH ? `${text.slice(0, DATA_PREVIEW_LENGTH - 1)}\u2026` : text;
|
|
11301
|
+
}
|
|
11206
11302
|
function formatEvent(event, context2) {
|
|
11207
11303
|
const { writer } = context2;
|
|
11208
|
-
const
|
|
11209
|
-
|
|
11304
|
+
const remote = serverEventOf(event);
|
|
11305
|
+
let time = event.timestamp;
|
|
11306
|
+
let type = event.type;
|
|
11307
|
+
let source = event.source;
|
|
11210
11308
|
let data = "";
|
|
11211
|
-
if (
|
|
11309
|
+
if (remote) {
|
|
11310
|
+
const sent = remote.data?.timestamp;
|
|
11311
|
+
if (typeof sent === "string" && !isNaN(Date.parse(sent))) time = sent;
|
|
11312
|
+
type = remote.type;
|
|
11313
|
+
source = remote.server;
|
|
11314
|
+
data = formatServerEventFields(remote.data);
|
|
11315
|
+
} else if (event.data !== void 0) {
|
|
11212
11316
|
try {
|
|
11213
11317
|
data = JSON.stringify(event.data) ?? "";
|
|
11214
11318
|
} catch {
|
|
11215
11319
|
data = String(event.data);
|
|
11216
11320
|
}
|
|
11217
|
-
|
|
11218
|
-
data = `${data.slice(0, DATA_PREVIEW_LENGTH - 1)}\u2026`;
|
|
11219
|
-
}
|
|
11321
|
+
data = shorten(data);
|
|
11220
11322
|
}
|
|
11221
|
-
|
|
11323
|
+
const when = new Date(time).toISOString().slice(11, 23);
|
|
11324
|
+
const from = source ? ` ${writer.wrapInColor(`[${source}]`, remote ? cliCore.CliForegroundColor.Magenta : cliCore.CliForegroundColor.Blue)}` : "";
|
|
11325
|
+
return `${writer.wrapInColor(when, cliCore.CliForegroundColor.Yellow)} ${writer.wrapInColor(type, cliCore.CliForegroundColor.Cyan)}${from}${data ? ` ${data}` : ""}`;
|
|
11326
|
+
}
|
|
11327
|
+
function filterOf(command2) {
|
|
11328
|
+
const server = command2.args["server"] ?? command2.args["s"];
|
|
11329
|
+
return {
|
|
11330
|
+
pattern: cliCore.joinShellWords(command2.value ?? "") || "*",
|
|
11331
|
+
server: server === void 0 || server === true ? void 0 : String(server),
|
|
11332
|
+
local: !!(command2.args["local"] || command2.args["l"])
|
|
11333
|
+
};
|
|
11222
11334
|
}
|
|
11335
|
+
var FILTER_PARAMETERS = [
|
|
11336
|
+
{
|
|
11337
|
+
name: "server",
|
|
11338
|
+
aliases: ["s"],
|
|
11339
|
+
type: "string",
|
|
11340
|
+
description: "Only the events of this server",
|
|
11341
|
+
required: false
|
|
11342
|
+
},
|
|
11343
|
+
{
|
|
11344
|
+
name: "local",
|
|
11345
|
+
aliases: ["l"],
|
|
11346
|
+
type: "boolean",
|
|
11347
|
+
description: "Only the terminal's own events",
|
|
11348
|
+
required: false
|
|
11349
|
+
}
|
|
11350
|
+
];
|
|
11223
11351
|
function busOf(context2) {
|
|
11224
11352
|
if (!context2.events) {
|
|
11225
11353
|
context2.writer.writeError(
|
|
@@ -11231,7 +11359,7 @@ function busOf(context2) {
|
|
|
11231
11359
|
var CliEventsCommandProcessor = class {
|
|
11232
11360
|
constructor() {
|
|
11233
11361
|
this.command = "events";
|
|
11234
|
-
this.description = "Watch, list and emit events
|
|
11362
|
+
this.description = "Watch, list and emit events of the terminal and the connected servers";
|
|
11235
11363
|
this.author = cliCore.DefaultLibraryAuthor;
|
|
11236
11364
|
this.version = "1.0.0";
|
|
11237
11365
|
this.metadata = {
|
|
@@ -11244,16 +11372,17 @@ var CliEventsCommandProcessor = class {
|
|
|
11244
11372
|
command: "watch",
|
|
11245
11373
|
description: "Print events as they happen (Ctrl+C to stop)",
|
|
11246
11374
|
acceptsRawInput: true,
|
|
11375
|
+
parameters: FILTER_PARAMETERS,
|
|
11247
11376
|
processCommand: async (command2, context2) => {
|
|
11248
11377
|
const bus = busOf(context2);
|
|
11249
11378
|
if (!bus) return;
|
|
11250
|
-
const
|
|
11379
|
+
const filter2 = filterOf(command2);
|
|
11251
11380
|
context2.writer.writeInfo(
|
|
11252
|
-
`Watching ${context2.writer.wrapInColor(pattern, cliCore.CliForegroundColor.Cyan)} \u2014 press Ctrl+C to stop`
|
|
11381
|
+
`Watching ${context2.writer.wrapInColor(filter2.pattern, cliCore.CliForegroundColor.Cyan)} \u2014 press Ctrl+C to stop`
|
|
11253
11382
|
);
|
|
11254
11383
|
await new Promise((resolve) => {
|
|
11255
|
-
const off = bus.on(
|
|
11256
|
-
if (canSee(event, context2)) {
|
|
11384
|
+
const off = bus.on("*", (event) => {
|
|
11385
|
+
if (matchesFilter(event, filter2) && canSee(event, context2)) {
|
|
11257
11386
|
context2.writer.writeln(formatEvent(event, context2));
|
|
11258
11387
|
}
|
|
11259
11388
|
});
|
|
@@ -11279,6 +11408,12 @@ var CliEventsCommandProcessor = class {
|
|
|
11279
11408
|
context2.writer.writeln(
|
|
11280
11409
|
` events watch boot:completed ${t.t("cli.events.watch.help.one_type", "One type")}`
|
|
11281
11410
|
);
|
|
11411
|
+
context2.writer.writeln(
|
|
11412
|
+
` events watch job:* -s node ${t.t("cli.events.watch.help.server_jobs", "Job events of the server node")}`
|
|
11413
|
+
);
|
|
11414
|
+
context2.writer.writeln(
|
|
11415
|
+
` events watch --local ${t.t("cli.events.watch.help.local_only", "Only the terminal's own events")}`
|
|
11416
|
+
);
|
|
11282
11417
|
}
|
|
11283
11418
|
},
|
|
11284
11419
|
{
|
|
@@ -11287,6 +11422,7 @@ var CliEventsCommandProcessor = class {
|
|
|
11287
11422
|
description: "Show recent events (kept in memory, not persisted)",
|
|
11288
11423
|
acceptsRawInput: true,
|
|
11289
11424
|
parameters: [
|
|
11425
|
+
...FILTER_PARAMETERS,
|
|
11290
11426
|
{
|
|
11291
11427
|
name: "limit",
|
|
11292
11428
|
aliases: ["n"],
|
|
@@ -11298,13 +11434,13 @@ var CliEventsCommandProcessor = class {
|
|
|
11298
11434
|
processCommand: async (command2, context2) => {
|
|
11299
11435
|
const bus = busOf(context2);
|
|
11300
11436
|
if (!bus) return;
|
|
11301
|
-
const
|
|
11437
|
+
const filter2 = filterOf(command2);
|
|
11302
11438
|
const limit = Number(
|
|
11303
11439
|
command2.args["limit"] ?? command2.args["n"] ?? 20
|
|
11304
11440
|
);
|
|
11305
|
-
const events = bus.history(
|
|
11441
|
+
const events = bus.history("*").filter((event) => matchesFilter(event, filter2) && canSee(event, context2)).slice(-(limit > 0 ? limit : 20));
|
|
11306
11442
|
if (events.length === 0) {
|
|
11307
|
-
context2.writer.writeInfo(`No events matching ${pattern}`);
|
|
11443
|
+
context2.writer.writeInfo(`No events matching ${filter2.pattern}`);
|
|
11308
11444
|
return;
|
|
11309
11445
|
}
|
|
11310
11446
|
for (const event of events) {
|
|
@@ -11323,6 +11459,9 @@ var CliEventsCommandProcessor = class {
|
|
|
11323
11459
|
context2.writer.writeln(
|
|
11324
11460
|
` events log server:* -n 50 ${t.t("cli.events.log.help.last_50_server", "Last 50 server events")}`
|
|
11325
11461
|
);
|
|
11462
|
+
context2.writer.writeln(
|
|
11463
|
+
` events log job:failed ${t.t("cli.events.log.help.failed_jobs", "Recent failed job runs, on every server")}`
|
|
11464
|
+
);
|
|
11326
11465
|
}
|
|
11327
11466
|
},
|
|
11328
11467
|
{
|
|
@@ -11394,6 +11533,9 @@ var CliEventsCommandProcessor = class {
|
|
|
11394
11533
|
writer.writeln(
|
|
11395
11534
|
t.t("cli.events.help.patterns", "Patterns: an exact type (package:installed), a namespace (package:*) or * for all.")
|
|
11396
11535
|
);
|
|
11536
|
+
writer.writeln(
|
|
11537
|
+
t.t("cli.events.help.servers", "Events of the connected servers (job runs, user, token and file changes, ...) are shown with the server name; each server sends only the events you may see. Filter with --server <name>, or --local for the terminal's own events.")
|
|
11538
|
+
);
|
|
11397
11539
|
writer.writeln(
|
|
11398
11540
|
t.t("cli.events.help.in_memory", "Events are kept in memory for this terminal only; nothing is persisted.")
|
|
11399
11541
|
);
|
|
@@ -12165,6 +12307,53 @@ var themeInfos = {
|
|
|
12165
12307
|
...cliCore.DefaultThemeInfos
|
|
12166
12308
|
};
|
|
12167
12309
|
|
|
12310
|
+
// src/lib/processors/theme/terminal-theme.ts
|
|
12311
|
+
var records = /* @__PURE__ */ new WeakMap();
|
|
12312
|
+
function recordOf(terminal) {
|
|
12313
|
+
let record = records.get(terminal);
|
|
12314
|
+
if (!record) {
|
|
12315
|
+
record = { base: terminal.options.theme ?? {}, userChosen: false };
|
|
12316
|
+
records.set(terminal, record);
|
|
12317
|
+
}
|
|
12318
|
+
return record;
|
|
12319
|
+
}
|
|
12320
|
+
var CLI_TERMINAL_THEME_EVENT = "qcli-terminal-theme";
|
|
12321
|
+
function paintTerminalBackground(terminal) {
|
|
12322
|
+
const container = terminal.element?.closest(".terminal-container");
|
|
12323
|
+
if (!container) return;
|
|
12324
|
+
const theme = terminal.options.theme ?? {};
|
|
12325
|
+
container.style.background = theme.background ?? "";
|
|
12326
|
+
if (typeof CustomEvent === "function") {
|
|
12327
|
+
container.dispatchEvent(new CustomEvent(CLI_TERMINAL_THEME_EVENT, { bubbles: true, detail: theme }));
|
|
12328
|
+
}
|
|
12329
|
+
}
|
|
12330
|
+
function setHostTerminalTheme(terminal, theme) {
|
|
12331
|
+
const record = recordOf(terminal);
|
|
12332
|
+
record.base = theme;
|
|
12333
|
+
if (!record.userChosen) {
|
|
12334
|
+
terminal.options.theme = theme;
|
|
12335
|
+
paintTerminalBackground(terminal);
|
|
12336
|
+
}
|
|
12337
|
+
}
|
|
12338
|
+
function applyUserTerminalTheme(terminal, theme) {
|
|
12339
|
+
recordOf(terminal).userChosen = true;
|
|
12340
|
+
terminal.options.theme = theme;
|
|
12341
|
+
paintTerminalBackground(terminal);
|
|
12342
|
+
}
|
|
12343
|
+
function resetTerminalTheme(terminal) {
|
|
12344
|
+
const record = recordOf(terminal);
|
|
12345
|
+
record.userChosen = false;
|
|
12346
|
+
terminal.options.theme = { ...record.base };
|
|
12347
|
+
paintTerminalBackground(terminal);
|
|
12348
|
+
}
|
|
12349
|
+
function previewTerminalTheme(terminal, theme) {
|
|
12350
|
+
terminal.options.theme = theme;
|
|
12351
|
+
paintTerminalBackground(terminal);
|
|
12352
|
+
}
|
|
12353
|
+
function initTerminalTheme(terminal) {
|
|
12354
|
+
recordOf(terminal);
|
|
12355
|
+
}
|
|
12356
|
+
|
|
12168
12357
|
// src/lib/processors/theme/cli-theme-command-processor.ts
|
|
12169
12358
|
function hexToRgb(hex) {
|
|
12170
12359
|
const m = /^#?([0-9A-Fa-f]{6})$/.exec(hex);
|
|
@@ -12365,15 +12554,19 @@ var CliThemeCommandProcessor = class {
|
|
|
12365
12554
|
{
|
|
12366
12555
|
onChange: (value) => {
|
|
12367
12556
|
if (themes[value]) {
|
|
12368
|
-
|
|
12369
|
-
|
|
12557
|
+
previewTerminalTheme(
|
|
12558
|
+
context2.terminal,
|
|
12559
|
+
themes[value]
|
|
12560
|
+
);
|
|
12370
12561
|
}
|
|
12371
12562
|
}
|
|
12372
12563
|
}
|
|
12373
12564
|
);
|
|
12374
12565
|
if (!selected) {
|
|
12375
|
-
|
|
12376
|
-
|
|
12566
|
+
previewTerminalTheme(
|
|
12567
|
+
context2.terminal,
|
|
12568
|
+
originalTheme
|
|
12569
|
+
);
|
|
12377
12570
|
context2.writer.writeInfo(
|
|
12378
12571
|
"Theme selection cancelled"
|
|
12379
12572
|
);
|
|
@@ -12387,13 +12580,12 @@ var CliThemeCommandProcessor = class {
|
|
|
12387
12580
|
);
|
|
12388
12581
|
return;
|
|
12389
12582
|
}
|
|
12390
|
-
context2.terminal
|
|
12583
|
+
applyUserTerminalTheme(context2.terminal, themes[themeName]);
|
|
12391
12584
|
context2.state.updateState({
|
|
12392
12585
|
selectedTheme: themeName,
|
|
12393
12586
|
customOptions: null
|
|
12394
12587
|
});
|
|
12395
12588
|
await context2.state.persist();
|
|
12396
|
-
this.applyStyles(context2);
|
|
12397
12589
|
context2.writer.writeSuccess(`Theme "${themeName}" applied`);
|
|
12398
12590
|
}
|
|
12399
12591
|
},
|
|
@@ -12429,10 +12621,10 @@ var CliThemeCommandProcessor = class {
|
|
|
12429
12621
|
);
|
|
12430
12622
|
return;
|
|
12431
12623
|
}
|
|
12432
|
-
context2.terminal
|
|
12624
|
+
applyUserTerminalTheme(context2.terminal, {
|
|
12433
12625
|
...context2.terminal.options.theme,
|
|
12434
12626
|
[key]: value
|
|
12435
|
-
};
|
|
12627
|
+
});
|
|
12436
12628
|
context2.state.updateState({
|
|
12437
12629
|
selectedTheme: null,
|
|
12438
12630
|
customOptions: context2.terminal.options.theme
|
|
@@ -12441,7 +12633,6 @@ var CliThemeCommandProcessor = class {
|
|
|
12441
12633
|
context2.writer.writeSuccess(
|
|
12442
12634
|
`Set ${key} to ${swatch} ${value}`
|
|
12443
12635
|
);
|
|
12444
|
-
this.applyStyles(context2);
|
|
12445
12636
|
if (command2.args["save"]) {
|
|
12446
12637
|
await this.saveTheme(context2);
|
|
12447
12638
|
}
|
|
@@ -12467,10 +12658,9 @@ var CliThemeCommandProcessor = class {
|
|
|
12467
12658
|
command: "reset",
|
|
12468
12659
|
description: "Reset the theme to the default",
|
|
12469
12660
|
processCommand: async (_, context2) => {
|
|
12470
|
-
context2.terminal
|
|
12661
|
+
resetTerminalTheme(context2.terminal);
|
|
12471
12662
|
context2.state.reset();
|
|
12472
12663
|
await context2.state.persist();
|
|
12473
|
-
this.applyStyles(context2);
|
|
12474
12664
|
context2.writer.writeSuccess("Theme reset to default");
|
|
12475
12665
|
}
|
|
12476
12666
|
},
|
|
@@ -12528,13 +12718,12 @@ var CliThemeCommandProcessor = class {
|
|
|
12528
12718
|
);
|
|
12529
12719
|
}
|
|
12530
12720
|
const [name, info] = candidates[Math.floor(Math.random() * candidates.length)];
|
|
12531
|
-
context2.terminal
|
|
12721
|
+
applyUserTerminalTheme(context2.terminal, info.theme);
|
|
12532
12722
|
context2.state.updateState({
|
|
12533
12723
|
selectedTheme: name,
|
|
12534
12724
|
customOptions: null
|
|
12535
12725
|
});
|
|
12536
12726
|
await context2.state.persist();
|
|
12537
|
-
this.applyStyles(context2);
|
|
12538
12727
|
context2.writer.writeSuccess(
|
|
12539
12728
|
`Random theme "${name}" applied`
|
|
12540
12729
|
);
|
|
@@ -12585,13 +12774,12 @@ var CliThemeCommandProcessor = class {
|
|
|
12585
12774
|
);
|
|
12586
12775
|
return;
|
|
12587
12776
|
}
|
|
12588
|
-
context2.terminal
|
|
12777
|
+
applyUserTerminalTheme(context2.terminal, imported);
|
|
12589
12778
|
context2.state.updateState({
|
|
12590
12779
|
selectedTheme: null,
|
|
12591
12780
|
customOptions: imported
|
|
12592
12781
|
});
|
|
12593
12782
|
await context2.state.persist();
|
|
12594
|
-
this.applyStyles(context2);
|
|
12595
12783
|
context2.writer.writeSuccess(
|
|
12596
12784
|
"Custom theme imported and applied"
|
|
12597
12785
|
);
|
|
@@ -12600,8 +12788,7 @@ var CliThemeCommandProcessor = class {
|
|
|
12600
12788
|
];
|
|
12601
12789
|
}
|
|
12602
12790
|
async initialize(context2) {
|
|
12603
|
-
|
|
12604
|
-
if (context2.options?.theme !== void 0) return;
|
|
12791
|
+
initTerminalTheme(context2.terminal);
|
|
12605
12792
|
this.applySavedTheme(context2, false);
|
|
12606
12793
|
context2.state.select(
|
|
12607
12794
|
(state) => JSON.stringify([
|
|
@@ -12613,17 +12800,14 @@ var CliThemeCommandProcessor = class {
|
|
|
12613
12800
|
/** Apply the saved theme (or the default one when `reset` and none is saved). */
|
|
12614
12801
|
applySavedTheme(context2, reset) {
|
|
12615
12802
|
const state = context2.state.getState();
|
|
12616
|
-
|
|
12617
|
-
|
|
12618
|
-
|
|
12619
|
-
context2.terminal.options.theme = theme;
|
|
12620
|
-
}
|
|
12621
|
-
} else if (state.customOptions) {
|
|
12622
|
-
context2.terminal.options.theme = state.customOptions;
|
|
12803
|
+
const saved = state.selectedTheme && state.selectedTheme !== "default" ? themes[state.selectedTheme] : state.customOptions;
|
|
12804
|
+
if (saved) {
|
|
12805
|
+
applyUserTerminalTheme(context2.terminal, saved);
|
|
12623
12806
|
} else if (reset) {
|
|
12624
|
-
context2.terminal
|
|
12807
|
+
resetTerminalTheme(context2.terminal);
|
|
12808
|
+
} else {
|
|
12809
|
+
paintTerminalBackground(context2.terminal);
|
|
12625
12810
|
}
|
|
12626
|
-
this.applyStyles(context2);
|
|
12627
12811
|
}
|
|
12628
12812
|
async processCommand(command2, context2) {
|
|
12629
12813
|
context2.executor.showHelp(command2, context2);
|
|
@@ -12702,12 +12886,6 @@ var CliThemeCommandProcessor = class {
|
|
|
12702
12886
|
);
|
|
12703
12887
|
}
|
|
12704
12888
|
}
|
|
12705
|
-
applyStyles(context2) {
|
|
12706
|
-
const parents = document.getElementsByClassName("terminal-container");
|
|
12707
|
-
for (const parent of Array.from(parents)) {
|
|
12708
|
-
parent.style.background = context2.terminal.options.theme?.background || this.defaultTheme.background;
|
|
12709
|
-
}
|
|
12710
|
-
}
|
|
12711
12889
|
async saveTheme(context2) {
|
|
12712
12890
|
await context2.state.persist();
|
|
12713
12891
|
context2.writer.writeSuccess("Theme saved");
|
|
@@ -13208,6 +13386,7 @@ var CliEnvCommandProcessor = class {
|
|
|
13208
13386
|
var MIN_FONT_SIZE = 8;
|
|
13209
13387
|
var MAX_FONT_SIZE = 40;
|
|
13210
13388
|
var STEP = 2;
|
|
13389
|
+
var hostFontSizes = /* @__PURE__ */ new WeakMap();
|
|
13211
13390
|
var CliFontSizeCommandProcessor = class {
|
|
13212
13391
|
constructor() {
|
|
13213
13392
|
this.command = "font-size";
|
|
@@ -13262,14 +13441,16 @@ var CliFontSizeCommandProcessor = class {
|
|
|
13262
13441
|
];
|
|
13263
13442
|
}
|
|
13264
13443
|
async initialize(context2) {
|
|
13265
|
-
|
|
13444
|
+
if (context2.terminal) {
|
|
13445
|
+
hostFontSizes.set(context2.terminal, context2.terminal.options?.fontSize);
|
|
13446
|
+
}
|
|
13266
13447
|
const state = context2.state.getState();
|
|
13267
13448
|
if (state?.fontSize != null && context2.terminal?.options) {
|
|
13268
13449
|
context2.terminal.options.fontSize = state.fontSize;
|
|
13269
13450
|
}
|
|
13270
13451
|
context2.state.select((s) => s.fontSize ?? null).pipe(operators.skip(1)).subscribe((fontSize) => {
|
|
13271
13452
|
if (!context2.terminal?.options) return;
|
|
13272
|
-
context2.terminal.options.fontSize = fontSize ?? this.
|
|
13453
|
+
context2.terminal.options.fontSize = fontSize ?? this.getDefault(context2);
|
|
13273
13454
|
});
|
|
13274
13455
|
}
|
|
13275
13456
|
async processCommand(_, context2) {
|
|
@@ -13287,7 +13468,7 @@ var CliFontSizeCommandProcessor = class {
|
|
|
13287
13468
|
` ${context2.writer.wrapInColor("font-size set <n>", cliCore.CliForegroundColor.Cyan)} Set to exact size`
|
|
13288
13469
|
);
|
|
13289
13470
|
context2.writer.writeln(
|
|
13290
|
-
` ${context2.writer.wrapInColor("font-size reset", cliCore.CliForegroundColor.Cyan)} Reset to default (${this.getDefault()}px)`
|
|
13471
|
+
` ${context2.writer.wrapInColor("font-size reset", cliCore.CliForegroundColor.Cyan)} Reset to default (${this.getDefault(context2)}px)`
|
|
13291
13472
|
);
|
|
13292
13473
|
}
|
|
13293
13474
|
writeDescription(context2) {
|
|
@@ -13320,13 +13501,13 @@ var CliFontSizeCommandProcessor = class {
|
|
|
13320
13501
|
return fromTerminal;
|
|
13321
13502
|
}
|
|
13322
13503
|
const state = context2.state.getState();
|
|
13323
|
-
return state?.fontSize ?? this.getDefault();
|
|
13504
|
+
return state?.fontSize ?? this.getDefault(context2);
|
|
13324
13505
|
}
|
|
13325
|
-
getDefault() {
|
|
13326
|
-
return
|
|
13506
|
+
getDefault(context2) {
|
|
13507
|
+
return (context2.terminal && hostFontSizes.get(context2.terminal)) ?? defaultFontSize();
|
|
13327
13508
|
}
|
|
13328
13509
|
async resetFontSize(context2) {
|
|
13329
|
-
const size = this.getDefault();
|
|
13510
|
+
const size = this.getDefault(context2);
|
|
13330
13511
|
if (context2.terminal?.options) {
|
|
13331
13512
|
context2.terminal.options.fontSize = size;
|
|
13332
13513
|
}
|
|
@@ -21960,73 +22141,6 @@ function createServerModule() {
|
|
|
21960
22141
|
services: []
|
|
21961
22142
|
};
|
|
21962
22143
|
}
|
|
21963
|
-
var CLI_EVENT_HISTORY_SIZE = 200;
|
|
21964
|
-
function matchesEventPattern(type, pattern) {
|
|
21965
|
-
if (pattern === "*") return true;
|
|
21966
|
-
if (pattern.endsWith(":*")) {
|
|
21967
|
-
return type.startsWith(pattern.slice(0, -1));
|
|
21968
|
-
}
|
|
21969
|
-
return type === pattern;
|
|
21970
|
-
}
|
|
21971
|
-
var CliEventBus = class {
|
|
21972
|
-
constructor(onHandlerError = (error) => console.error("[CLI] Event handler failed:", error), historySize = CLI_EVENT_HISTORY_SIZE) {
|
|
21973
|
-
this.onHandlerError = onHandlerError;
|
|
21974
|
-
this.historySize = historySize;
|
|
21975
|
-
this.subject = new rxjs.Subject();
|
|
21976
|
-
this.recent = [];
|
|
21977
|
-
this.disposed = false;
|
|
21978
|
-
}
|
|
21979
|
-
emit(type, data, options) {
|
|
21980
|
-
if (this.disposed) return;
|
|
21981
|
-
const event = {
|
|
21982
|
-
type,
|
|
21983
|
-
data,
|
|
21984
|
-
source: options?.source,
|
|
21985
|
-
timestamp: Date.now()
|
|
21986
|
-
};
|
|
21987
|
-
this.recent.push(event);
|
|
21988
|
-
if (this.recent.length > this.historySize) {
|
|
21989
|
-
this.recent.shift();
|
|
21990
|
-
}
|
|
21991
|
-
this.subject.next(event);
|
|
21992
|
-
}
|
|
21993
|
-
on(pattern, handler) {
|
|
21994
|
-
const subscription = this.events$(pattern).subscribe((event) => {
|
|
21995
|
-
try {
|
|
21996
|
-
handler(event);
|
|
21997
|
-
} catch (error) {
|
|
21998
|
-
this.onHandlerError(error, event);
|
|
21999
|
-
}
|
|
22000
|
-
});
|
|
22001
|
-
return () => subscription.unsubscribe();
|
|
22002
|
-
}
|
|
22003
|
-
once(pattern, handler) {
|
|
22004
|
-
let done = false;
|
|
22005
|
-
const unsubscribe = this.on(pattern, (event) => {
|
|
22006
|
-
if (done) return;
|
|
22007
|
-
done = true;
|
|
22008
|
-
unsubscribe();
|
|
22009
|
-
handler(event);
|
|
22010
|
-
});
|
|
22011
|
-
return unsubscribe;
|
|
22012
|
-
}
|
|
22013
|
-
events$(pattern = "*") {
|
|
22014
|
-
return this.subject.asObservable().pipe(operators.filter((event) => matchesEventPattern(event.type, pattern)));
|
|
22015
|
-
}
|
|
22016
|
-
history(pattern = "*", limit) {
|
|
22017
|
-
const matching = this.recent.filter(
|
|
22018
|
-
(event) => matchesEventPattern(event.type, pattern)
|
|
22019
|
-
);
|
|
22020
|
-
return limit !== void 0 ? matching.slice(-limit) : matching;
|
|
22021
|
-
}
|
|
22022
|
-
/** Stop delivering events and complete all observables. */
|
|
22023
|
-
dispose() {
|
|
22024
|
-
if (this.disposed) return;
|
|
22025
|
-
this.disposed = true;
|
|
22026
|
-
this.subject.complete();
|
|
22027
|
-
this.recent.length = 0;
|
|
22028
|
-
}
|
|
22029
|
-
};
|
|
22030
22144
|
|
|
22031
22145
|
// src/lib/editor/syntax/registry.ts
|
|
22032
22146
|
var SyntaxHighlighterRegistry = class {
|
|
@@ -23128,12 +23242,13 @@ var CliEngine = class {
|
|
|
23128
23242
|
});
|
|
23129
23243
|
}
|
|
23130
23244
|
/**
|
|
23131
|
-
*
|
|
23132
|
-
*
|
|
23245
|
+
* The host's theme for this terminal: its colors and the background around it.
|
|
23246
|
+
* A theme the user chose with the `theme` command stays until `theme reset`,
|
|
23247
|
+
* which returns to this one.
|
|
23133
23248
|
*/
|
|
23134
23249
|
setTheme(theme) {
|
|
23135
|
-
if (this.terminal) this.terminal
|
|
23136
|
-
this.container.style.background = theme.background ?? "";
|
|
23250
|
+
if (this.terminal) setHostTerminalTheme(this.terminal, theme);
|
|
23251
|
+
else this.container.style.background = theme.background ?? "";
|
|
23137
23252
|
}
|
|
23138
23253
|
/**
|
|
23139
23254
|
* Get the underlying xterm.js Terminal instance.
|
|
@@ -23238,6 +23353,8 @@ var CliEngine = class {
|
|
|
23238
23353
|
window.addEventListener("resize", this.resizeListener);
|
|
23239
23354
|
this.resizeObserver = new ResizeObserver(() => this.safeFit());
|
|
23240
23355
|
this.resizeObserver.observe(this.container);
|
|
23356
|
+
const screen2 = this.terminal?.element?.querySelector(".xterm-screen");
|
|
23357
|
+
if (screen2) this.resizeObserver.observe(screen2);
|
|
23241
23358
|
}
|
|
23242
23359
|
/**
|
|
23243
23360
|
* Call fitAddon.fit() only when the container has non-zero dimensions.
|
|
@@ -23984,6 +24101,9 @@ function sameJson(a, b) {
|
|
|
23984
24101
|
}
|
|
23985
24102
|
var PANE_RESIZING_BODY_CLASS = "cli-pane-resizing";
|
|
23986
24103
|
var DARK_SCHEME_QUERY = "(prefers-color-scheme: dark)";
|
|
24104
|
+
function asEventTarget(node) {
|
|
24105
|
+
return node && typeof node.addEventListener === "function" ? node : null;
|
|
24106
|
+
}
|
|
23987
24107
|
function followsSystem(input) {
|
|
23988
24108
|
return input === "auto" || typeof input === "object" && input !== null && input.base === "auto";
|
|
23989
24109
|
}
|
|
@@ -24058,6 +24178,13 @@ var CliPanelController = class {
|
|
|
24058
24178
|
this.cancelRename();
|
|
24059
24179
|
};
|
|
24060
24180
|
this.onSystemSchemeChange = () => this.applyTheme();
|
|
24181
|
+
/** A terminal in the panel changed theme: follow the first one. */
|
|
24182
|
+
this.onTerminalTheme = (event) => {
|
|
24183
|
+
if (!this.followsTerminalTheme) return;
|
|
24184
|
+
const first = this.rootElement?.querySelector(".terminal-container");
|
|
24185
|
+
if (event.target !== first) return;
|
|
24186
|
+
this.syncThemeFromEngine(event.detail);
|
|
24187
|
+
};
|
|
24061
24188
|
this.onVisualViewportChange = () => {
|
|
24062
24189
|
const fields = visualViewportFields();
|
|
24063
24190
|
const s = this.snapshot;
|
|
@@ -24130,7 +24257,7 @@ var CliPanelController = class {
|
|
|
24130
24257
|
return;
|
|
24131
24258
|
}
|
|
24132
24259
|
this.commit(fields);
|
|
24133
|
-
if (
|
|
24260
|
+
if (this.followsTerminalTheme) this.startThemeSync();
|
|
24134
24261
|
else this.stopThemeSync();
|
|
24135
24262
|
}
|
|
24136
24263
|
/**
|
|
@@ -24141,6 +24268,15 @@ var CliPanelController = class {
|
|
|
24141
24268
|
this.themeInput = theme;
|
|
24142
24269
|
this.watchSystemScheme();
|
|
24143
24270
|
this.applyTheme();
|
|
24271
|
+
if (this.followsTerminalTheme) this.startThemeSync();
|
|
24272
|
+
else this.stopThemeSync();
|
|
24273
|
+
}
|
|
24274
|
+
/**
|
|
24275
|
+
* Whether the panel's colors follow its first terminal: with `syncTheme`, or
|
|
24276
|
+
* with a host theme so a theme the user applies restyles the panel too.
|
|
24277
|
+
*/
|
|
24278
|
+
get followsTerminalTheme() {
|
|
24279
|
+
return this.snapshot.syncTheme || this.themeInput !== void 0;
|
|
24144
24280
|
}
|
|
24145
24281
|
/** Replace the change callbacks (wrappers call this when their props change). */
|
|
24146
24282
|
setCallbacks(callbacks) {
|
|
@@ -24156,8 +24292,11 @@ var CliPanelController = class {
|
|
|
24156
24292
|
}
|
|
24157
24293
|
/** Element containing the terminals, used for theme sync. */
|
|
24158
24294
|
setRootElement(element) {
|
|
24295
|
+
if (element === this.rootElement) return;
|
|
24296
|
+
asEventTarget(this.rootElement)?.removeEventListener(CLI_TERMINAL_THEME_EVENT, this.onTerminalTheme);
|
|
24159
24297
|
this.rootElement = element;
|
|
24160
|
-
|
|
24298
|
+
asEventTarget(element)?.addEventListener(CLI_TERMINAL_THEME_EVENT, this.onTerminalTheme);
|
|
24299
|
+
if (element && this.followsTerminalTheme) this.startThemeSync();
|
|
24161
24300
|
}
|
|
24162
24301
|
/**
|
|
24163
24302
|
* Stop timers, observers and document listeners. Engines are not
|
|
@@ -24385,10 +24524,11 @@ var CliPanelController = class {
|
|
|
24385
24524
|
/** Called by the view once a pane's terminal engine is running. */
|
|
24386
24525
|
registerEngine(tabId, paneId, engine) {
|
|
24387
24526
|
if (!this.findTab(tabId)) return;
|
|
24527
|
+
const known = this.engines.get(paneId) === engine;
|
|
24388
24528
|
this.engines.set(paneId, engine);
|
|
24389
24529
|
this.tracker.registerEngine(tabId, paneId, engine);
|
|
24390
|
-
if (this.snapshot.terminalTheme) engine.setTheme(this.snapshot.terminalTheme);
|
|
24391
|
-
if (this.
|
|
24530
|
+
if (this.snapshot.terminalTheme && !known) engine.setTheme(this.snapshot.terminalTheme);
|
|
24531
|
+
if (this.followsTerminalTheme) this.startThemeSync();
|
|
24392
24532
|
}
|
|
24393
24533
|
getEngine(paneId) {
|
|
24394
24534
|
return this.engines.get(paneId ?? this.snapshot.activePaneId);
|
|
@@ -24533,11 +24673,12 @@ var CliPanelController = class {
|
|
|
24533
24673
|
this.documentListenersAttached = false;
|
|
24534
24674
|
}
|
|
24535
24675
|
/* ─── Theme sync ────────────────────────────────────────── */
|
|
24536
|
-
/** Read the first terminal's theme and derive the panel colours from it. */
|
|
24537
|
-
syncThemeFromEngine() {
|
|
24538
|
-
|
|
24539
|
-
|
|
24540
|
-
|
|
24676
|
+
/** Read the first terminal's theme (or use `theme`) and derive the panel colours from it. */
|
|
24677
|
+
syncThemeFromEngine(theme) {
|
|
24678
|
+
if (!theme) {
|
|
24679
|
+
const engine = this.engines.values().next().value;
|
|
24680
|
+
theme = engine?.getTerminal().options.theme;
|
|
24681
|
+
}
|
|
24541
24682
|
if (!theme) return;
|
|
24542
24683
|
const styles = sameTerminalTheme(theme, this.resolvedTheme.terminal) ? this.resolvedTheme.styles : cliCore.derivePanelThemeStyles(theme);
|
|
24543
24684
|
if (sameRecord(styles, this.snapshot.themeStyles)) return;
|
|
@@ -24564,7 +24705,7 @@ var CliPanelController = class {
|
|
|
24564
24705
|
const themeStyles = this.themeInput === void 0 ? {} : resolved.styles;
|
|
24565
24706
|
this.commit({ themeStyles, scheme: resolved.scheme, terminalTheme });
|
|
24566
24707
|
if (terminalChanged) this.engines.forEach((engine) => engine.setTheme(terminalTheme));
|
|
24567
|
-
if (this.
|
|
24708
|
+
if (this.followsTerminalTheme) this.syncThemeFromEngine();
|
|
24568
24709
|
}
|
|
24569
24710
|
/** Follow the system's light/dark setting while the theme is 'auto'. */
|
|
24570
24711
|
watchSystemScheme() {
|
|
@@ -24663,7 +24804,7 @@ var CliPanelController = class {
|
|
|
24663
24804
|
if (this.themeObserver) {
|
|
24664
24805
|
this.stopThemeSync();
|
|
24665
24806
|
setTimeout(() => {
|
|
24666
|
-
if (this.
|
|
24807
|
+
if (this.followsTerminalTheme && !this.themeObserver) this.startThemeSync();
|
|
24667
24808
|
}, 0);
|
|
24668
24809
|
}
|
|
24669
24810
|
try {
|