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