@qodalis/cli 2.1.0 → 2.1.1

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.
@@ -90,6 +90,8 @@
90
90
 
91
91
  .cli-panel-title {
92
92
  font-size: 0.95rem;
93
+ white-space: nowrap;
94
+ min-width: 0;
93
95
  display: flex;
94
96
  gap: 0.5rem;
95
97
  justify-content: center;
@@ -668,6 +670,32 @@
668
670
 
669
671
  /* Phones: icon only, so the tab covers as little of the page as possible */
670
672
  @media (max-width: 600px) {
673
+ /* The header keeps the title on one line; moving the panel to another
674
+ edge makes no sense on a phone */
675
+ .cli-panel-header-content {
676
+ gap: 0.5rem;
677
+ padding: 0 0.5rem 0 0.75rem;
678
+ }
679
+
680
+ .cli-panel-title {
681
+ overflow: hidden;
682
+ text-overflow: ellipsis;
683
+ }
684
+
685
+ .cli-panel-action-buttons {
686
+ gap: 0.15rem;
687
+ flex-shrink: 0;
688
+ }
689
+
690
+ .cli-panel-action-buttons .cli-panel-btn {
691
+ width: 34px;
692
+ height: 34px;
693
+ }
694
+
695
+ .cli-panel-btn-position-wrapper {
696
+ display: none;
697
+ }
698
+
671
699
  .cli-panel-hide-tab {
672
700
  padding: 6px 8px;
673
701
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qodalis/cli",
3
- "version": "2.1.0",
3
+ "version": "2.1.1",
4
4
  "description": "Framework-agnostic CLI engine for @qodalis terminal applications.",
5
5
  "author": "Nicolae Lupei, Qodalis Solutions",
6
6
  "license": "MIT",
@@ -30,7 +30,7 @@
30
30
  "./assets/*": "./assets/*"
31
31
  },
32
32
  "dependencies": {
33
- "@qodalis/cli-core": "2.1.0",
33
+ "@qodalis/cli-core": "2.1.1",
34
34
  "@xterm/xterm": "^6.0.0",
35
35
  "@xterm/addon-fit": "^0.11.0",
36
36
  "@xterm/addon-web-links": "^0.12.0",
package/public-api.d.mts CHANGED
@@ -165,7 +165,7 @@ declare const CliKeyValueStore_TOKEN: any;
165
165
  */
166
166
  declare const SyntaxHighlighterRegistry_TOKEN: any;
167
167
 
168
- declare const LIBRARY_VERSION = "2.1.0";
168
+ declare const LIBRARY_VERSION = "2.1.1";
169
169
  declare const API_VERSION = 2;
170
170
 
171
171
  declare class CliAliasCommandProcessor implements ICliCommandProcessor {
@@ -3182,6 +3182,12 @@ declare class CliServerConnection {
3182
3182
  onReconnected?: () => void;
3183
3183
  constructor(_config: CliServerConfig, _backgroundServices?: ICliBackgroundServiceRegistry, _logger?: ICliLogger, _authService?: ICliServerAuthService);
3184
3184
  get config(): CliServerConfig;
3185
+ /**
3186
+ * The last connect was refused for want of a sign-in (401 or 403 on the
3187
+ * command list): the server is up, and a sign-in reconnects it.
3188
+ */
3189
+ get needsSignIn(): boolean;
3190
+ private _needsSignIn;
3185
3191
  get connected(): boolean;
3186
3192
  get commands(): CliServerCommandDescriptor[];
3187
3193
  get capabilities(): CliServerCapabilities | null;
package/public-api.d.ts CHANGED
@@ -165,7 +165,7 @@ declare const CliKeyValueStore_TOKEN: any;
165
165
  */
166
166
  declare const SyntaxHighlighterRegistry_TOKEN: any;
167
167
 
168
- declare const LIBRARY_VERSION = "2.1.0";
168
+ declare const LIBRARY_VERSION = "2.1.1";
169
169
  declare const API_VERSION = 2;
170
170
 
171
171
  declare class CliAliasCommandProcessor implements ICliCommandProcessor {
@@ -3182,6 +3182,12 @@ declare class CliServerConnection {
3182
3182
  onReconnected?: () => void;
3183
3183
  constructor(_config: CliServerConfig, _backgroundServices?: ICliBackgroundServiceRegistry, _logger?: ICliLogger, _authService?: ICliServerAuthService);
3184
3184
  get config(): CliServerConfig;
3185
+ /**
3186
+ * The last connect was refused for want of a sign-in (401 or 403 on the
3187
+ * command list): the server is up, and a sign-in reconnects it.
3188
+ */
3189
+ get needsSignIn(): boolean;
3190
+ private _needsSignIn;
3185
3191
  get connected(): boolean;
3186
3192
  get commands(): CliServerCommandDescriptor[];
3187
3193
  get capabilities(): CliServerCapabilities | null;
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.1.0";
522
+ var LIBRARY_VERSION = "2.1.1";
523
523
  var API_VERSION = 2;
524
524
  var ANONYMOUS = "\0anonymous";
525
525
  function aliasOwner(context2) {
@@ -5398,6 +5398,7 @@ var CliServerConnection = class _CliServerConnection {
5398
5398
  this._eventServiceRegistered = false;
5399
5399
  this._healthCheckTimer = null;
5400
5400
  this._healthCheckAttempts = 0;
5401
+ this._needsSignIn = false;
5401
5402
  }
5402
5403
  static {
5403
5404
  this.WS_MAX_RECONNECT_ATTEMPTS = 5;
@@ -5414,6 +5415,13 @@ var CliServerConnection = class _CliServerConnection {
5414
5415
  get config() {
5415
5416
  return this._config;
5416
5417
  }
5418
+ /**
5419
+ * The last connect was refused for want of a sign-in (401 or 403 on the
5420
+ * command list): the server is up, and a sign-in reconnects it.
5421
+ */
5422
+ get needsSignIn() {
5423
+ return this._needsSignIn;
5424
+ }
5417
5425
  get connected() {
5418
5426
  return this._connected;
5419
5427
  }
@@ -5453,6 +5461,7 @@ var CliServerConnection = class _CliServerConnection {
5453
5461
  });
5454
5462
  }
5455
5463
  async connect() {
5464
+ this._needsSignIn = false;
5456
5465
  try {
5457
5466
  const baseUrl = this.normalizeUrl(this._config.url);
5458
5467
  const negotiated = await cliCore.ServerVersionNegotiator.discover(
@@ -5535,6 +5544,7 @@ var CliServerConnection = class _CliServerConnection {
5535
5544
  const url = `${this._basePath}/commands`;
5536
5545
  const response = await this.httpFetch(url);
5537
5546
  if (!response.ok) {
5547
+ if (response.status === 401 || response.status === 403) this._needsSignIn = true;
5538
5548
  throw new Error(
5539
5549
  `Server ${this._config.name} returned ${response.status}`
5540
5550
  );
@@ -6225,6 +6235,10 @@ var CliServerManager = class {
6225
6235
  );
6226
6236
  this.registerProxyProcessors(connection, config.name);
6227
6237
  this.emitConnected(connection, false);
6238
+ } else if (connection.needsSignIn) {
6239
+ logger?.info(
6240
+ `Server '${config.name}' needs a sign-in; its commands load once you are signed in.`
6241
+ );
6228
6242
  } else {
6229
6243
  logger?.warn(
6230
6244
  `Could not connect to server '${config.name}' at ${config.url}. Commands from this server will not be available.`
@@ -19294,8 +19308,9 @@ var welcomeModule = {
19294
19308
  );
19295
19309
  await configureStore.initialize();
19296
19310
  const state = configureStore.getState();
19297
- if (state?.["system"]?.["welcomeMessage"]) {
19298
- showOption = state["system"]["welcomeMessage"];
19311
+ const stored = state?.["system"]?.["welcomeMessage"];
19312
+ if (stored && stored !== "always") {
19313
+ showOption = stored;
19299
19314
  }
19300
19315
  }
19301
19316
  if (showOption) {
@@ -19308,10 +19323,11 @@ var welcomeModule = {
19308
19323
  context2.terminal.writeln(config.message);
19309
19324
  } else {
19310
19325
  const branding = resolveCliBranding(context2.options?.branding);
19326
+ const art = branding.art(context2.terminal.cols);
19311
19327
  const lines = [
19312
19328
  `\u{1F680} Welcome to ${branding.name} [Version ${context2.writer.wrapInColor(LIBRARY_VERSION, cliCore.CliForegroundColor.Green)}]`,
19313
19329
  `(c) ${(/* @__PURE__ */ new Date()).getFullYear()} Qodalis Solutions. All rights reserved.`,
19314
- branding.art(context2.terminal.cols),
19330
+ art,
19315
19331
  "",
19316
19332
  `\u{1F4D6} ${context2.writer.wrapInColor("Documentation:", cliCore.CliForegroundColor.Green)} https://cli.qodalis.com/docs/`,
19317
19333
  "",
@@ -19319,7 +19335,10 @@ var welcomeModule = {
19319
19335
  ""
19320
19336
  ];
19321
19337
  lines.forEach((line2) => {
19322
- context2.terminal.write(line2 + "\r\n");
19338
+ const wrapped = line2 === art ? [line2] : wrapWelcomeLine(line2, context2.terminal.cols);
19339
+ wrapped.forEach(
19340
+ (part) => context2.terminal.write(part + "\r\n")
19341
+ );
19323
19342
  });
19324
19343
  }
19325
19344
  recordWelcomeMessageDisplay();
@@ -19351,12 +19370,51 @@ var greetingModule = {
19351
19370
  if (host.typedDuringBoot || host.isReadingInput || context2.currentLine) {
19352
19371
  return;
19353
19372
  }
19354
- await context2.textAnimator?.showText(getGreetingBasedOnTime(), {
19373
+ const buffer = context2.terminal.buffer?.active;
19374
+ const room = context2.terminal.cols - (buffer?.cursorX ?? 0) - 1;
19375
+ const greeting = fitGreeting(getGreetingBasedOnTime(), room);
19376
+ if (!greeting) return;
19377
+ await context2.textAnimator?.showText(greeting, {
19355
19378
  speed: 60,
19356
19379
  removeAfterTyping: true
19357
19380
  });
19358
19381
  }
19359
19382
  };
19383
+ function fitGreeting(text, room) {
19384
+ const width = (value) => Array.from(value).reduce(
19385
+ (sum, ch) => sum + (ch.codePointAt(0) > 65535 || /\p{Extended_Pictographic}/u.test(ch) ? 2 : ch === "\uFE0F" ? 0 : 1),
19386
+ 0
19387
+ );
19388
+ if (width(text) <= room) return text;
19389
+ const words = text.split(" ");
19390
+ let fitted = "";
19391
+ for (const word of words) {
19392
+ const next = fitted ? `${fitted} ${word}` : word;
19393
+ if (width(next) > room) break;
19394
+ fitted = next;
19395
+ }
19396
+ return fitted.split(" ").length >= 3 ? fitted.replace(/[,;:]$/, "") : null;
19397
+ }
19398
+ function wrapWelcomeLine(line2, cols) {
19399
+ const width = Math.max(20, cols - 1);
19400
+ const visible = (value) => Array.from(value.replace(/\x1b\[[0-9;]*m/g, "")).reduce(
19401
+ (sum, ch) => sum + (ch.codePointAt(0) > 65535 ? 2 : ch === "\uFE0F" ? 0 : 1),
19402
+ 0
19403
+ );
19404
+ if (visible(line2) <= width) return [line2];
19405
+ const lines = [];
19406
+ let current = "";
19407
+ for (const word of line2.split(" ")) {
19408
+ if (current && visible(current) + 1 + visible(word) > width) {
19409
+ lines.push(current);
19410
+ current = word;
19411
+ } else {
19412
+ current = current ? `${current} ${word}` : word;
19413
+ }
19414
+ }
19415
+ if (current) lines.push(current);
19416
+ return lines;
19417
+ }
19360
19418
  function shouldDisplayWelcomeMessage(showOption) {
19361
19419
  const lastDisplayed = localStorage.getItem(
19362
19420
  "cliWelcomeMessageLastDisplayed"
@@ -24088,7 +24146,9 @@ var CliPanelController = class {
24088
24146
  unhide() {
24089
24147
  if (!this.snapshot.hidden) return;
24090
24148
  this.updateHidden(false);
24091
- if (this.snapshot.collapsed !== this.preHideCollapsed) this.updateCollapsed(this.preHideCollapsed);
24149
+ const collapsed = this.snapshot.initialized ? this.preHideCollapsed : false;
24150
+ if (this.snapshot.collapsed !== collapsed) this.updateCollapsed(collapsed);
24151
+ if (!collapsed) this.ensureInitialized();
24092
24152
  }
24093
24153
  toggleHide() {
24094
24154
  if (this.snapshot.hidden) this.unhide();