@franzzemen/brokenstock-shell 0.0.3 → 0.0.4

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/README.md ADDED
@@ -0,0 +1,19 @@
1
+ # @franzzemen/brokenstock-shell
2
+
3
+ Shared Angular shell library for Brokenstock web applications. Provides the foundational layout (resizable command terminal, side menu, status bar), authentication infrastructure, command dispatch pipeline, and theming — all configured via injection tokens so consuming apps supply only their domain-specific commands, menu items, and status content.
4
+
5
+ ## Documentation
6
+
7
+ | Document | Audience | Description |
8
+ |----------|----------|-------------|
9
+ | [brokenstock-shell.intent.md](doc/intent/brokenstock-shell.intent.md) | AI agents | Purpose, design invariants, boundaries, guidance |
10
+ | [brokenstock-shell.guide.md](doc/guide/brokenstock-shell.guide.md) | Engineers (maintainers) | Architecture, service internals, component structure, build/publish |
11
+ | [brokenstock-shell.usage.md](doc/usage/brokenstock-shell.usage.md) | Engineers (consumers) | Installation, setup examples, API reference, type quick reference |
12
+
13
+ ## Core Concepts
14
+
15
+ - **Injection token configuration:** `SHELL_APP_NAME`, `SHELL_AUTH_URLS`, `SHELL_MENU_ITEMS`, `SHELL_COMMANDS`
16
+ - **Content projection:** App-specific status bar items projected through `<shell-root>` into the status bar
17
+ - **Command pattern:** `@Injectable` classes implementing `CommandDefinition`, registered via `SHELL_COMMANDS` token
18
+ - **Signal-based state:** All services use Angular signals; no RxJS in public APIs
19
+ - **Peer dependencies:** Angular 21, Material, CDK, @franzzemen/identity, @franzzemen/utility, zod, rxjs
@@ -23,6 +23,8 @@ import * as i4 from '@angular/material/input';
23
23
  import { MatInput, MatInputModule } from '@angular/material/input';
24
24
  import * as i6 from '@angular/material/button';
25
25
  import { MatButtonModule } from '@angular/material/button';
26
+ import * as i7 from '@angular/material/checkbox';
27
+ import { MatCheckboxModule } from '@angular/material/checkbox';
26
28
  import * as i1$2 from '@angular/material/dialog';
27
29
  import { MAT_DIALOG_DATA, MatDialogRef, MatDialogModule } from '@angular/material/dialog';
28
30
 
@@ -45,8 +47,11 @@ function provideShellConfig(config) {
45
47
  }
46
48
 
47
49
  class ThinkingService {
48
- #activeCount = signal(0, ...(ngDevMode ? [{ debugName: "#activeCount" }] : /* istanbul ignore next */ []));
49
- isThinking = computed(() => this.#activeCount() > 0, ...(ngDevMode ? [{ debugName: "isThinking" }] : /* istanbul ignore next */ []));
50
+ constructor() {
51
+ this.#activeCount = signal(0, ...(ngDevMode ? [{ debugName: "#activeCount" }] : /* istanbul ignore next */ []));
52
+ this.isThinking = computed(() => this.#activeCount() > 0, ...(ngDevMode ? [{ debugName: "isThinking" }] : /* istanbul ignore next */ []));
53
+ }
54
+ #activeCount;
50
55
  startThinking() {
51
56
  this.#activeCount.update(c => c + 1);
52
57
  }
@@ -56,8 +61,8 @@ class ThinkingService {
56
61
  reset() {
57
62
  this.#activeCount.set(0);
58
63
  }
59
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: ThinkingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
60
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: ThinkingService, providedIn: 'root' });
64
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: ThinkingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
65
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: ThinkingService, providedIn: 'root' }); }
61
66
  }
62
67
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: ThinkingService, decorators: [{
63
68
  type: Injectable,
@@ -65,17 +70,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImpor
65
70
  }] });
66
71
 
67
72
  class AuthenticationService {
68
- authenticated = signal(false, ...(ngDevMode ? [{ debugName: "authenticated" }] : /* istanbul ignore next */ []));
69
- authenticating = signal(false, ...(ngDevMode ? [{ debugName: "authenticating" }] : /* istanbul ignore next */ []));
70
- userSession = signal(undefined, ...(ngDevMode ? [{ debugName: "userSession" }] : /* istanbul ignore next */ []));
71
- effectivePermissions = signal({}, ...(ngDevMode ? [{ debugName: "effectivePermissions" }] : /* istanbul ignore next */ []));
72
- conflictSessions = signal(undefined, ...(ngDevMode ? [{ debugName: "conflictSessions" }] : /* istanbul ignore next */ []));
73
- #refreshing = null;
74
- #auth = 'Bearer ..';
75
- #httpClient = inject(HttpClient);
76
- #thinkingService = inject(ThinkingService);
77
- #router = inject(Router);
78
- #authUrls = inject(SHELL_AUTH_URLS);
73
+ constructor() {
74
+ this.authenticated = signal(false, ...(ngDevMode ? [{ debugName: "authenticated" }] : /* istanbul ignore next */ []));
75
+ this.authenticating = signal(false, ...(ngDevMode ? [{ debugName: "authenticating" }] : /* istanbul ignore next */ []));
76
+ this.userSession = signal(undefined, ...(ngDevMode ? [{ debugName: "userSession" }] : /* istanbul ignore next */ []));
77
+ this.effectivePermissions = signal({}, ...(ngDevMode ? [{ debugName: "effectivePermissions" }] : /* istanbul ignore next */ []));
78
+ this.conflictSessions = signal(undefined, ...(ngDevMode ? [{ debugName: "conflictSessions" }] : /* istanbul ignore next */ []));
79
+ this.#refreshing = null;
80
+ this.#auth = 'Bearer ..';
81
+ this.#httpClient = inject(HttpClient);
82
+ this.#thinkingService = inject(ThinkingService);
83
+ this.#router = inject(Router);
84
+ this.#authUrls = inject(SHELL_AUTH_URLS);
85
+ }
86
+ #refreshing;
87
+ #auth;
88
+ #httpClient;
89
+ #thinkingService;
90
+ #router;
91
+ #authUrls;
79
92
  get auth() {
80
93
  return this.#auth;
81
94
  }
@@ -211,8 +224,8 @@ class AuthenticationService {
211
224
  this.#auth = 'Bearer ..';
212
225
  this.#router.navigate(['/login']).catch(console.error);
213
226
  }
214
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: AuthenticationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
215
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: AuthenticationService, providedIn: 'root' });
227
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: AuthenticationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
228
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: AuthenticationService, providedIn: 'root' }); }
216
229
  }
217
230
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: AuthenticationService, decorators: [{
218
231
  type: Injectable,
@@ -267,15 +280,17 @@ const authInterceptor = (req, next) => {
267
280
  };
268
281
 
269
282
  class RegexValidatorDirective {
270
- regex = input(/^[A-Z0-9._%+-@!?]{4,64}$/i, ...(ngDevMode ? [{ debugName: "regex" }] : /* istanbul ignore next */ []));
283
+ constructor() {
284
+ this.regex = input(/^[A-Z0-9._%+-@!?]{4,64}$/i, ...(ngDevMode ? [{ debugName: "regex" }] : /* istanbul ignore next */ []));
285
+ }
271
286
  validate(control) {
272
287
  if (!control.value || !this.regex().test(control.value)) {
273
288
  return { regexValidator: { value: control.value } };
274
289
  }
275
290
  return null;
276
291
  }
277
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: RegexValidatorDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
278
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.7", type: RegexValidatorDirective, isStandalone: true, selector: "[regexValidator]", inputs: { regex: { classPropertyName: "regex", publicName: "regex", isSignal: true, isRequired: false, transformFunction: null } }, providers: [{ provide: NG_VALIDATORS, useExisting: RegexValidatorDirective, multi: true }], ngImport: i0 });
292
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: RegexValidatorDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
293
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.7", type: RegexValidatorDirective, isStandalone: true, selector: "[regexValidator]", inputs: { regex: { classPropertyName: "regex", publicName: "regex", isSignal: true, isRequired: false, transformFunction: null } }, providers: [{ provide: NG_VALIDATORS, useExisting: RegexValidatorDirective, multi: true }], ngImport: i0 }); }
279
294
  }
280
295
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: RegexValidatorDirective, decorators: [{
281
296
  type: Directive,
@@ -286,10 +301,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImpor
286
301
  }], propDecorators: { regex: [{ type: i0.Input, args: [{ isSignal: true, alias: "regex", required: false }] }] } });
287
302
 
288
303
  class ThemeService {
289
- mode = signal('dark', ...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
290
- isDark = computed(() => this.mode() === 'dark', ...(ngDevMode ? [{ debugName: "isDark" }] : /* istanbul ignore next */ []));
291
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: ThemeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
292
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: ThemeService, providedIn: 'root' });
304
+ constructor() {
305
+ this.mode = signal('dark', ...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
306
+ this.isDark = computed(() => this.mode() === 'dark', ...(ngDevMode ? [{ debugName: "isDark" }] : /* istanbul ignore next */ []));
307
+ }
308
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: ThemeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
309
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: ThemeService, providedIn: 'root' }); }
293
310
  }
294
311
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: ThemeService, decorators: [{
295
312
  type: Injectable,
@@ -297,12 +314,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImpor
297
314
  }] });
298
315
 
299
316
  class TerminalFocusService {
300
- focusRequested = signal(0, ...(ngDevMode ? [{ debugName: "focusRequested" }] : /* istanbul ignore next */ []));
317
+ constructor() {
318
+ this.focusRequested = signal(0, ...(ngDevMode ? [{ debugName: "focusRequested" }] : /* istanbul ignore next */ []));
319
+ }
301
320
  requestFocus() {
302
321
  this.focusRequested.update(v => v + 1);
303
322
  }
304
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: TerminalFocusService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
305
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: TerminalFocusService, providedIn: 'root' });
323
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: TerminalFocusService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
324
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: TerminalFocusService, providedIn: 'root' }); }
306
325
  }
307
326
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: TerminalFocusService, decorators: [{
308
327
  type: Injectable,
@@ -310,22 +329,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImpor
310
329
  }] });
311
330
 
312
331
  class KeyboardShortcutService {
313
- #groups = new Map();
314
- #activeGroupId = signal(null, ...(ngDevMode ? [{ debugName: "#activeGroupId" }] : /* istanbul ignore next */ []));
315
- #document = inject(DOCUMENT);
316
- #zone = inject(NgZone);
317
- #focusService = inject(TerminalFocusService);
318
- helpVisible = signal(false, ...(ngDevMode ? [{ debugName: "helpVisible" }] : /* istanbul ignore next */ []));
319
- activeShortcuts = computed(() => {
320
- const groupId = this.#activeGroupId();
321
- if (!groupId)
322
- return null;
323
- const shortcuts = this.#groups.get(groupId);
324
- if (!shortcuts)
325
- return null;
326
- return { groupId, shortcuts };
327
- }, ...(ngDevMode ? [{ debugName: "activeShortcuts" }] : /* istanbul ignore next */ []));
332
+ #groups;
333
+ #activeGroupId;
334
+ #document;
335
+ #zone;
336
+ #focusService;
328
337
  constructor() {
338
+ this.#groups = new Map();
339
+ this.#activeGroupId = signal(null, ...(ngDevMode ? [{ debugName: "#activeGroupId" }] : /* istanbul ignore next */ []));
340
+ this.#document = inject(DOCUMENT);
341
+ this.#zone = inject(NgZone);
342
+ this.#focusService = inject(TerminalFocusService);
343
+ this.helpVisible = signal(false, ...(ngDevMode ? [{ debugName: "helpVisible" }] : /* istanbul ignore next */ []));
344
+ this.activeShortcuts = computed(() => {
345
+ const groupId = this.#activeGroupId();
346
+ if (!groupId)
347
+ return null;
348
+ const shortcuts = this.#groups.get(groupId);
349
+ if (!shortcuts)
350
+ return null;
351
+ return { groupId, shortcuts };
352
+ }, ...(ngDevMode ? [{ debugName: "activeShortcuts" }] : /* istanbul ignore next */ []));
329
353
  this.#zone.runOutsideAngular(() => {
330
354
  this.#document.addEventListener('keydown', (event) => {
331
355
  this.#handleKeydown(event);
@@ -380,8 +404,8 @@ class KeyboardShortcutService {
380
404
  }
381
405
  return false;
382
406
  }
383
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: KeyboardShortcutService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
384
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: KeyboardShortcutService, providedIn: 'root' });
407
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: KeyboardShortcutService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
408
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: KeyboardShortcutService, providedIn: 'root' }); }
385
409
  }
386
410
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: KeyboardShortcutService, decorators: [{
387
411
  type: Injectable,
@@ -389,8 +413,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImpor
389
413
  }], ctorParameters: () => [] });
390
414
 
391
415
  class CommandRegistryService {
392
- commands = new Map();
393
416
  constructor() {
417
+ this.commands = new Map();
394
418
  const appCommands = inject(SHELL_COMMANDS, { optional: true }) ?? [];
395
419
  for (const cmd of appCommands) {
396
420
  this.register(cmd);
@@ -421,8 +445,8 @@ class CommandRegistryService {
421
445
  .filter(name => name.startsWith(prefix) && name !== prefix)
422
446
  .sort();
423
447
  }
424
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: CommandRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
425
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: CommandRegistryService, providedIn: 'root' });
448
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: CommandRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
449
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: CommandRegistryService, providedIn: 'root' }); }
426
450
  }
427
451
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: CommandRegistryService, decorators: [{
428
452
  type: Injectable,
@@ -446,22 +470,22 @@ const HELP_USAGE = 'help [command]\n\n' +
446
470
 
447
471
  const CommandInputSchema = z.string().trim().min(1, 'Command cannot be empty');
448
472
  class CommandService {
449
- history = signal([], ...(ngDevMode ? [{ debugName: "history" }] : /* istanbul ignore next */ []));
450
- currentInput = signal('', ...(ngDevMode ? [{ debugName: "currentInput" }] : /* istanbul ignore next */ []));
451
- isProcessing = signal(false, ...(ngDevMode ? [{ debugName: "isProcessing" }] : /* istanbul ignore next */ []));
452
- authService = inject(AuthenticationService);
453
- registry = inject(CommandRegistryService);
454
473
  constructor() {
474
+ this.history = signal([], ...(ngDevMode ? [{ debugName: "history" }] : /* istanbul ignore next */ []));
475
+ this.currentInput = signal('', ...(ngDevMode ? [{ debugName: "currentInput" }] : /* istanbul ignore next */ []));
476
+ this.isProcessing = signal(false, ...(ngDevMode ? [{ debugName: "isProcessing" }] : /* istanbul ignore next */ []));
477
+ this.authService = inject(AuthenticationService);
478
+ this.registry = inject(CommandRegistryService);
479
+ this.lastResult = computed(() => {
480
+ const h = this.history();
481
+ return h.length > 0 ? h[h.length - 1].result : null;
482
+ }, ...(ngDevMode ? [{ debugName: "lastResult" }] : /* istanbul ignore next */ []));
455
483
  effect(() => {
456
484
  if (!this.authService.authenticated()) {
457
485
  this.history.set([]);
458
486
  }
459
487
  });
460
488
  }
461
- lastResult = computed(() => {
462
- const h = this.history();
463
- return h.length > 0 ? h[h.length - 1].result : null;
464
- }, ...(ngDevMode ? [{ debugName: "lastResult" }] : /* istanbul ignore next */ []));
465
489
  echoCommand(input) {
466
490
  if (this.#coalesce(input))
467
491
  return;
@@ -585,8 +609,8 @@ class CommandService {
585
609
  return { success: false, message: `Unknown command: ${name}`, timestamp: new Date() };
586
610
  return { success: true, message: def.usage, timestamp: new Date() };
587
611
  }
588
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: CommandService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
589
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: CommandService, providedIn: 'root' });
612
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: CommandService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
613
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: CommandService, providedIn: 'root' }); }
590
614
  }
591
615
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: CommandService, decorators: [{
592
616
  type: Injectable,
@@ -594,22 +618,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImpor
594
618
  }], ctorParameters: () => [] });
595
619
 
596
620
  class StatusBar {
597
- #authService = inject(AuthenticationService);
598
- #focusService = inject(TerminalFocusService);
599
- #commandService = inject(CommandService);
600
- isAuthenticated = this.#authService.authenticated;
601
- loginStatus = computed(() => this.#authService.authenticating()
602
- ? 'Authenticating...'
603
- : this.#authService.authenticated()
604
- ? 'Logged in'
605
- : 'Not logged in', ...(ngDevMode ? [{ debugName: "loginStatus" }] : /* istanbul ignore next */ []));
621
+ constructor() {
622
+ this.#authService = inject(AuthenticationService);
623
+ this.#focusService = inject(TerminalFocusService);
624
+ this.#commandService = inject(CommandService);
625
+ this.isAuthenticated = this.#authService.authenticated;
626
+ this.loginStatus = computed(() => this.#authService.authenticating()
627
+ ? 'Authenticating...'
628
+ : this.#authService.authenticated()
629
+ ? 'Logged in'
630
+ : 'Not logged in', ...(ngDevMode ? [{ debugName: "loginStatus" }] : /* istanbul ignore next */ []));
631
+ }
632
+ #authService;
633
+ #focusService;
634
+ #commandService;
606
635
  logout() {
607
636
  this.#authService.logout();
608
637
  this.#commandService.echoCommand('logout');
609
638
  this.#focusService.requestFocus();
610
639
  }
611
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: StatusBar, deps: [], target: i0.ɵɵFactoryTarget.Component });
612
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.7", type: StatusBar, isStandalone: true, selector: "shell-status-bar", ngImport: i0, template: "<div class=\"status-bar\">\n <div class=\"status-item\">\n <span class=\"status-label text-secondary-info\">Status:</span>\n @if (isAuthenticated()) {\n <a class=\"status-value text-interactive logout-link\" (click)=\"logout()\">Log Out</a>\n } @else {\n <span class=\"status-value text-loss\">{{ loginStatus() }}</span>\n }\n </div>\n @if (isAuthenticated()) {\n <ng-content />\n }\n</div>\n", styles: [".status-bar{display:flex;align-items:center;gap:24px;padding:0 16px;height:100%;background-color:var(--color-surface);border-bottom:1px solid var(--color-surface-border);font-size:.8rem}.status-item{display:flex;align-items:baseline;gap:6px}.status-label{font-weight:500;text-transform:uppercase;letter-spacing:.05em;font-size:.7rem}.logout-link{cursor:pointer;text-decoration:underline}.logout-link:hover{opacity:.8}\n"] });
640
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: StatusBar, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
641
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.7", type: StatusBar, isStandalone: true, selector: "shell-status-bar", ngImport: i0, template: "<div class=\"status-bar\">\n <div class=\"status-item\">\n <span class=\"status-label text-secondary-info\">Status:</span>\n @if (isAuthenticated()) {\n <a class=\"status-value text-interactive logout-link\" (click)=\"logout()\">Log Out</a>\n } @else {\n <span class=\"status-value text-loss\">{{ loginStatus() }}</span>\n }\n </div>\n @if (isAuthenticated()) {\n <ng-content />\n }\n</div>\n", styles: [".status-bar{display:flex;align-items:center;gap:24px;padding:0 16px;height:100%;background-color:var(--color-surface);border-bottom:1px solid var(--color-surface-border);font-size:.8rem}.status-item{display:flex;align-items:baseline;gap:6px}.status-label{font-weight:500;text-transform:uppercase;letter-spacing:.05em;font-size:.7rem}.logout-link{cursor:pointer;text-decoration:underline}.logout-link:hover{opacity:.8}\n"] }); }
613
642
  }
614
643
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: StatusBar, decorators: [{
615
644
  type: Component,
@@ -617,12 +646,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImpor
617
646
  }] });
618
647
 
619
648
  class SideMenu {
620
- #focusService = inject(TerminalFocusService);
621
- #commandService = inject(CommandService);
622
- #shortcutService = inject(KeyboardShortcutService);
623
- hasShortcuts = this.#shortcutService.activeShortcuts;
624
- #allMenuItems = inject(SHELL_MENU_ITEMS, { optional: true }) ?? [];
625
- menuItems = computed(() => this.#allMenuItems.filter(item => !item.visible || item.visible()), ...(ngDevMode ? [{ debugName: "menuItems" }] : /* istanbul ignore next */ []));
649
+ constructor() {
650
+ this.#focusService = inject(TerminalFocusService);
651
+ this.#commandService = inject(CommandService);
652
+ this.#shortcutService = inject(KeyboardShortcutService);
653
+ this.hasShortcuts = this.#shortcutService.activeShortcuts;
654
+ this.#allMenuItems = inject(SHELL_MENU_ITEMS, { optional: true }) ?? [];
655
+ this.menuItems = computed(() => this.#allMenuItems.filter(item => !item.visible || item.visible()), ...(ngDevMode ? [{ debugName: "menuItems" }] : /* istanbul ignore next */ []));
656
+ }
657
+ #focusService;
658
+ #commandService;
659
+ #shortcutService;
660
+ #allMenuItems;
626
661
  onMenuClick(item) {
627
662
  if (item.command) {
628
663
  this.#commandService.echoCommand(item.command);
@@ -632,8 +667,8 @@ class SideMenu {
632
667
  toggleHelp() {
633
668
  this.#shortcutService.toggleHelp();
634
669
  }
635
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: SideMenu, deps: [], target: i0.ɵɵFactoryTarget.Component });
636
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.7", type: SideMenu, isStandalone: true, selector: "shell-side-menu", ngImport: i0, template: "<nav class=\"side-menu\">\n @for (item of menuItems(); track item.route) {\n <a\n class=\"menu-item\"\n [routerLink]=\"item.route\"\n routerLinkActive=\"active\"\n [matTooltip]=\"item.label\"\n matTooltipPosition=\"right\"\n (click)=\"onMenuClick(item)\"\n >\n <mat-icon>{{ item.icon }}</mat-icon>\n </a>\n }\n <div class=\"menu-spacer\"></div>\n @if (hasShortcuts()) {\n <button\n class=\"help-button\"\n matTooltip=\"Keyboard shortcuts\"\n matTooltipPosition=\"right\"\n (click)=\"toggleHelp()\"\n >\n <span class=\"help-modifier\">Alt+</span><span class=\"help-key\">?</span>\n </button>\n }\n</nav>\n", styles: [".side-menu{display:flex;flex-direction:column;align-items:center;padding-top:8px;gap:4px;height:100%;background-color:var(--color-surface);border-right:1px solid var(--color-surface-border)}.menu-item{display:flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:8px;color:var(--color-secondary-info);text-decoration:none;transition:background-color .15s,color .15s}.menu-item:hover,.menu-item.active{background-color:var(--color-surface-light);color:var(--color-interactive)}.menu-spacer{flex:1}.help-button{margin-bottom:8px;padding:4px 6px;border:1px solid var(--color-surface-border);border-radius:6px;background:none;font-size:.7rem;font-family:Roboto Mono,monospace;cursor:pointer;color:var(--color-interactive);transition:background-color .15s}.help-button:hover{background-color:var(--color-surface-light)}.help-modifier{opacity:.6}.help-key{font-weight:700}\n"], dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
670
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: SideMenu, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
671
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.7", type: SideMenu, isStandalone: true, selector: "shell-side-menu", ngImport: i0, template: "<nav class=\"side-menu\">\n @for (item of menuItems(); track item.route) {\n <a\n class=\"menu-item\"\n [routerLink]=\"item.route\"\n routerLinkActive=\"active\"\n [matTooltip]=\"item.label\"\n matTooltipPosition=\"right\"\n (click)=\"onMenuClick(item)\"\n >\n <mat-icon>{{ item.icon }}</mat-icon>\n </a>\n }\n <div class=\"menu-spacer\"></div>\n @if (hasShortcuts()) {\n <button\n class=\"help-button\"\n matTooltip=\"Keyboard shortcuts\"\n matTooltipPosition=\"right\"\n (click)=\"toggleHelp()\"\n >\n <span class=\"help-modifier\">Alt+</span><span class=\"help-key\">?</span>\n </button>\n }\n</nav>\n", styles: [".side-menu{display:flex;flex-direction:column;align-items:center;padding-top:8px;gap:4px;height:100%;background-color:var(--color-surface);border-right:1px solid var(--color-surface-border)}.menu-item{display:flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:8px;color:var(--color-secondary-info);text-decoration:none;transition:background-color .15s,color .15s}.menu-item:hover,.menu-item.active{background-color:var(--color-surface-light);color:var(--color-interactive)}.menu-spacer{flex:1}.help-button{margin-bottom:8px;padding:4px 6px;border:1px solid var(--color-surface-border);border-radius:6px;background:none;font-size:.7rem;font-family:Roboto Mono,monospace;cursor:pointer;color:var(--color-interactive);transition:background-color .15s}.help-button:hover{background-color:var(--color-surface-light)}.help-modifier{opacity:.6}.help-key{font-weight:700}\n"], dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] }); }
637
672
  }
638
673
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: SideMenu, decorators: [{
639
674
  type: Component,
@@ -641,11 +676,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImpor
641
676
  }] });
642
677
 
643
678
  class MainContent {
644
- #thinkingService = inject(ThinkingService);
645
- #shortcutService = inject(KeyboardShortcutService);
646
- isThinking = this.#thinkingService.isThinking;
647
- shortcutHelpVisible = this.#shortcutService.helpVisible;
648
- activeShortcuts = this.#shortcutService.activeShortcuts;
679
+ constructor() {
680
+ this.#thinkingService = inject(ThinkingService);
681
+ this.#shortcutService = inject(KeyboardShortcutService);
682
+ this.isThinking = this.#thinkingService.isThinking;
683
+ this.shortcutHelpVisible = this.#shortcutService.helpVisible;
684
+ this.activeShortcuts = this.#shortcutService.activeShortcuts;
685
+ }
686
+ #thinkingService;
687
+ #shortcutService;
649
688
  formatKey(key) {
650
689
  const keyMap = {
651
690
  ArrowUp: '↑', ArrowDown: '↓', ArrowLeft: '←', ArrowRight: '→',
@@ -656,8 +695,8 @@ class MainContent {
656
695
  closeShortcutHelp() {
657
696
  this.#shortcutService.helpVisible.set(false);
658
697
  }
659
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: MainContent, deps: [], target: i0.ɵɵFactoryTarget.Component });
660
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.7", type: MainContent, isStandalone: true, selector: "shell-main-content", ngImport: i0, template: "<div class=\"main-content\">\n <div class=\"content-area\">\n <router-outlet />\n </div>\n @if (shortcutHelpVisible() && activeShortcuts()) {\n <div class=\"shortcut-overlay\" (click)=\"closeShortcutHelp()\">\n <div class=\"shortcut-panel\" (click)=\"$event.stopPropagation()\">\n <div class=\"shortcut-title text-secondary-info\">{{ activeShortcuts()!.groupId }} shortcuts</div>\n @for (s of activeShortcuts()!.shortcuts; track s.key) {\n <div class=\"shortcut-row\">\n <kbd class=\"shortcut-key\">Alt+{{ formatKey(s.key) }}</kbd>\n <span class=\"shortcut-desc text-text-primary\">{{ s.description }}</span>\n </div>\n }\n <div class=\"shortcut-row shortcut-dismiss\">\n <kbd class=\"shortcut-key\">Alt+?</kbd>\n <span class=\"shortcut-desc text-secondary-info\">or</span>\n <kbd class=\"shortcut-key\">Esc</kbd>\n <span class=\"shortcut-desc text-secondary-info\">dismiss</span>\n </div>\n </div>\n </div>\n }\n @if (isThinking()) {\n <div class=\"thinking-overlay\">\n <mat-spinner diameter=\"48\" />\n </div>\n }\n</div>\n", styles: [".main-content{position:relative;height:100%;overflow:hidden}.content-area{height:100%;overflow-y:auto;padding:16px}.shortcut-overlay{position:absolute;inset:0;z-index:15;display:flex;align-items:center;justify-content:center;background-color:#0a0e1480}.shortcut-panel{background-color:var(--color-terminal-bg);border:1px solid var(--color-surface-border);border-radius:6px;padding:14px 18px;font-size:.8rem;box-shadow:0 4px 16px #00000080;min-width:220px}.shortcut-title{font-size:.7rem;text-transform:uppercase;letter-spacing:.05em;margin-bottom:8px;font-weight:500}.shortcut-row{display:flex;align-items:center;gap:10px;padding:3px 0}.shortcut-row.shortcut-dismiss{margin-top:6px;border-top:1px solid var(--color-surface-border);padding-top:8px}.shortcut-key{font-family:Roboto Mono,monospace;font-size:.75rem;background-color:#ffffff14;border:1px solid var(--color-surface-border);border-radius:3px;padding:1px 6px;min-width:70px;text-align:center}.shortcut-desc{font-size:.78rem}.thinking-overlay{position:absolute;inset:0;z-index:20;background-color:#0a0e14b3;display:flex;align-items:center;justify-content:center;pointer-events:all;cursor:wait}\n"], dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i1$1.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }] });
698
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: MainContent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
699
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.7", type: MainContent, isStandalone: true, selector: "shell-main-content", ngImport: i0, template: "<div class=\"main-content\">\n <div class=\"content-area\">\n <router-outlet />\n </div>\n @if (shortcutHelpVisible() && activeShortcuts()) {\n <div class=\"shortcut-overlay\" (click)=\"closeShortcutHelp()\">\n <div class=\"shortcut-panel\" (click)=\"$event.stopPropagation()\">\n <div class=\"shortcut-title text-secondary-info\">{{ activeShortcuts()!.groupId }} shortcuts</div>\n @for (s of activeShortcuts()!.shortcuts; track s.key) {\n <div class=\"shortcut-row\">\n <kbd class=\"shortcut-key\">Alt+{{ formatKey(s.key) }}</kbd>\n <span class=\"shortcut-desc text-text-primary\">{{ s.description }}</span>\n </div>\n }\n <div class=\"shortcut-row shortcut-dismiss\">\n <kbd class=\"shortcut-key\">Alt+?</kbd>\n <span class=\"shortcut-desc text-secondary-info\">or</span>\n <kbd class=\"shortcut-key\">Esc</kbd>\n <span class=\"shortcut-desc text-secondary-info\">dismiss</span>\n </div>\n </div>\n </div>\n }\n @if (isThinking()) {\n <div class=\"thinking-overlay\">\n <mat-spinner diameter=\"48\" />\n </div>\n }\n</div>\n", styles: [".main-content{position:relative;height:100%;overflow:hidden}.content-area{height:100%;overflow-y:auto;padding:16px}.shortcut-overlay{position:absolute;inset:0;z-index:15;display:flex;align-items:center;justify-content:center;background-color:#0a0e1480}.shortcut-panel{background-color:var(--color-terminal-bg);border:1px solid var(--color-surface-border);border-radius:6px;padding:14px 18px;font-size:.8rem;box-shadow:0 4px 16px #00000080;min-width:220px}.shortcut-title{font-size:.7rem;text-transform:uppercase;letter-spacing:.05em;margin-bottom:8px;font-weight:500}.shortcut-row{display:flex;align-items:center;gap:10px;padding:3px 0}.shortcut-row.shortcut-dismiss{margin-top:6px;border-top:1px solid var(--color-surface-border);padding-top:8px}.shortcut-key{font-family:Roboto Mono,monospace;font-size:.75rem;background-color:#ffffff14;border:1px solid var(--color-surface-border);border-radius:3px;padding:1px 6px;min-width:70px;text-align:center}.shortcut-desc{font-size:.78rem}.thinking-overlay{position:absolute;inset:0;z-index:20;background-color:#0a0e14b3;display:flex;align-items:center;justify-content:center;pointer-events:all;cursor:wait}\n"], dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i1$1.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }] }); }
661
700
  }
662
701
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: MainContent, decorators: [{
663
702
  type: Component,
@@ -665,25 +704,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImpor
665
704
  }] });
666
705
 
667
706
  class CommandTerminal {
668
- commandService = inject(CommandService);
669
- registry = inject(CommandRegistryService);
670
- authService = inject(AuthenticationService);
671
- terminalFocusService = inject(TerminalFocusService);
672
- history = computed(() => [...this.commandService.history()].reverse(), ...(ngDevMode ? [{ debugName: "history" }] : /* istanbul ignore next */ []));
673
- currentInput = this.commandService.currentInput;
674
- isProcessing = this.commandService.isProcessing;
675
- inputEl = viewChild('terminalInput', ...(ngDevMode ? [{ debugName: "inputEl" }] : /* istanbul ignore next */ []));
676
- tabCycleIndex = -1;
677
- lastTabPrefix = '';
678
- ghostText = computed(() => {
679
- const input = this.currentInput().trim();
680
- if (!input || input.includes(' '))
681
- return '';
682
- const prefix = input.toLowerCase();
683
- const suggestions = this.registry.getSuggestions(prefix, this.authService.authenticated());
684
- return suggestions.length > 0 ? suggestions[0] : '';
685
- }, ...(ngDevMode ? [{ debugName: "ghostText" }] : /* istanbul ignore next */ []));
686
707
  constructor() {
708
+ this.commandService = inject(CommandService);
709
+ this.registry = inject(CommandRegistryService);
710
+ this.authService = inject(AuthenticationService);
711
+ this.terminalFocusService = inject(TerminalFocusService);
712
+ this.history = computed(() => [...this.commandService.history()].reverse(), ...(ngDevMode ? [{ debugName: "history" }] : /* istanbul ignore next */ []));
713
+ this.currentInput = this.commandService.currentInput;
714
+ this.isProcessing = this.commandService.isProcessing;
715
+ this.inputEl = viewChild('terminalInput', ...(ngDevMode ? [{ debugName: "inputEl" }] : /* istanbul ignore next */ []));
716
+ this.tabCycleIndex = -1;
717
+ this.lastTabPrefix = '';
718
+ this.ghostText = computed(() => {
719
+ const input = this.currentInput().trim();
720
+ if (!input || input.includes(' '))
721
+ return '';
722
+ const prefix = input.toLowerCase();
723
+ const suggestions = this.registry.getSuggestions(prefix, this.authService.authenticated());
724
+ return suggestions.length > 0 ? suggestions[0] : '';
725
+ }, ...(ngDevMode ? [{ debugName: "ghostText" }] : /* istanbul ignore next */ []));
687
726
  afterNextRender(() => this.focusInput());
688
727
  effect(() => {
689
728
  if (!this.isProcessing()) {
@@ -748,8 +787,8 @@ class CommandTerminal {
748
787
  focusInput() {
749
788
  this.inputEl()?.nativeElement.focus();
750
789
  }
751
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: CommandTerminal, deps: [], target: i0.ɵɵFactoryTarget.Component });
752
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.7", type: CommandTerminal, isStandalone: true, selector: "shell-command-terminal", viewQueries: [{ propertyName: "inputEl", first: true, predicate: ["terminalInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"terminal\">\n <div class=\"terminal-input-row\">\n <span class=\"prompt\">$</span>\n <div class=\"input-wrapper\">\n @if (ghostText()) {\n <input\n class=\"ghost-input\"\n type=\"text\"\n [value]=\"ghostText()\"\n disabled\n tabindex=\"-1\"\n aria-hidden=\"true\"\n />\n }\n <input\n #terminalInput\n class=\"terminal-input\"\n type=\"text\"\n [ngModel]=\"currentInput()\"\n (ngModelChange)=\"onInputChange($event)\"\n (keydown.enter)=\"onSubmit()\"\n (keydown.tab)=\"onTab($any($event))\"\n placeholder=\"Type a command...\"\n [disabled]=\"isProcessing()\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n />\n </div>\n </div>\n <div class=\"terminal-output\">\n @for (entry of history(); track entry.result.timestamp) {\n @if (entry.input) {\n <div class=\"terminal-line\">\n <span class=\"prompt\">$</span>\n <span class=\"command-text\">{{ entry.input }}@if ((entry.repeatCount ?? 1) > 1) { <span class=\"repeat-count\">(\u00D7{{ entry.repeatCount }})</span>}</span>\n </div>\n }\n @if (entry.result.message) {\n <div class=\"terminal-line\" [class]=\"getSeverityClass(entry.result)\">{{ entry.result.message }}</div>\n }\n }\n </div>\n</div>\n", styles: [".terminal{display:flex;flex-direction:column;height:100%;background-color:var(--color-terminal-bg);border-top:1px solid var(--color-surface-border);font-family:Roboto Mono,Courier New,monospace;font-size:.85rem}.terminal-output{flex:1;overflow-y:auto;padding:8px 12px;display:flex;flex-direction:column}.terminal-line{line-height:1.6;color:var(--color-text-primary);white-space:pre-wrap}.terminal-line.error{color:var(--color-loss)}.terminal-line.warning{color:var(--color-warning)}.terminal-line.info{color:var(--color-info)}.prompt{color:var(--color-terminal-prompt);margin-right:8px;font-weight:700}.command-text{color:var(--color-terminal-text)}.repeat-count{color:var(--color-secondary-info);opacity:.6;margin-left:4px}.terminal-input-row{display:flex;align-items:center;padding:8px 12px;border-bottom:1px solid var(--color-surface-border)}.input-wrapper{flex:1;display:grid}.ghost-input,.terminal-input{grid-area:1 / 1;font-family:inherit;font-size:inherit;line-height:normal;margin:0;padding:0;border:none;background:transparent;outline:none;-webkit-appearance:none;appearance:none;width:100%}.ghost-input{color:var(--color-secondary-info);opacity:.3;pointer-events:none}.terminal-input{color:var(--color-terminal-text);caret-color:var(--color-terminal-prompt)}.terminal-input::placeholder{color:var(--color-secondary-info);opacity:.5}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
790
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: CommandTerminal, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
791
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.7", type: CommandTerminal, isStandalone: true, selector: "shell-command-terminal", viewQueries: [{ propertyName: "inputEl", first: true, predicate: ["terminalInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"terminal\">\n <div class=\"terminal-input-row\">\n <span class=\"prompt\">$</span>\n <div class=\"input-wrapper\">\n @if (ghostText()) {\n <input\n class=\"ghost-input\"\n type=\"text\"\n [value]=\"ghostText()\"\n disabled\n tabindex=\"-1\"\n aria-hidden=\"true\"\n />\n }\n <input\n #terminalInput\n class=\"terminal-input\"\n type=\"text\"\n [ngModel]=\"currentInput()\"\n (ngModelChange)=\"onInputChange($event)\"\n (keydown.enter)=\"onSubmit()\"\n (keydown.tab)=\"onTab($any($event))\"\n placeholder=\"Type a command...\"\n [disabled]=\"isProcessing()\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n />\n </div>\n </div>\n <div class=\"terminal-output\">\n @for (entry of history(); track entry.result.timestamp) {\n @if (entry.input) {\n <div class=\"terminal-line\">\n <span class=\"prompt\">$</span>\n <span class=\"command-text\">{{ entry.input }}@if ((entry.repeatCount ?? 1) > 1) { <span class=\"repeat-count\">(\u00D7{{ entry.repeatCount }})</span>}</span>\n </div>\n }\n @if (entry.result.message) {\n <div class=\"terminal-line\" [class]=\"getSeverityClass(entry.result)\">{{ entry.result.message }}</div>\n }\n }\n </div>\n</div>\n", styles: [".terminal{display:flex;flex-direction:column;height:100%;background-color:var(--color-terminal-bg);border-top:1px solid var(--color-surface-border);font-family:Roboto Mono,Courier New,monospace;font-size:.85rem}.terminal-output{flex:1;overflow-y:auto;padding:8px 12px;display:flex;flex-direction:column}.terminal-line{line-height:1.6;color:var(--color-text-primary);white-space:pre-wrap}.terminal-line.error{color:var(--color-loss)}.terminal-line.warning{color:var(--color-warning)}.terminal-line.info{color:var(--color-info)}.prompt{color:var(--color-terminal-prompt);margin-right:8px;font-weight:700}.command-text{color:var(--color-terminal-text)}.repeat-count{color:var(--color-secondary-info);opacity:.6;margin-left:4px}.terminal-input-row{display:flex;align-items:center;padding:8px 12px;border-bottom:1px solid var(--color-surface-border)}.input-wrapper{flex:1;display:grid}.ghost-input,.terminal-input{grid-area:1 / 1;font-family:inherit;font-size:inherit;line-height:normal;margin:0;padding:0;border:none;background:transparent;outline:none;-webkit-appearance:none;appearance:none;width:100%}.ghost-input{color:var(--color-secondary-info);opacity:.3;pointer-events:none}.terminal-input{color:var(--color-terminal-text);caret-color:var(--color-terminal-prompt)}.terminal-input::placeholder{color:var(--color-secondary-info);opacity:.5}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] }); }
753
792
  }
754
793
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: CommandTerminal, decorators: [{
755
794
  type: Component,
@@ -760,23 +799,30 @@ const MIN_TERMINAL_HEIGHT = 80;
760
799
  const MAX_TERMINAL_RATIO = 0.6;
761
800
  const DEFAULT_TERMINAL_HEIGHT = 160;
762
801
  class Shell {
763
- #thinkingService = inject(ThinkingService);
764
- isThinking = this.#thinkingService.isThinking;
765
- terminalHeight = signal(`${DEFAULT_TERMINAL_HEIGHT}px`, ...(ngDevMode ? [{ debugName: "terminalHeight" }] : /* istanbul ignore next */ []));
766
- isDragging = signal(false, ...(ngDevMode ? [{ debugName: "isDragging" }] : /* istanbul ignore next */ []));
767
- #startY = 0;
768
- #startHeight = DEFAULT_TERMINAL_HEIGHT;
769
- #onMouseMove = (event) => {
770
- const deltaY = event.clientY - this.#startY;
771
- const maxHeight = Math.floor(window.innerHeight * MAX_TERMINAL_RATIO);
772
- const newHeight = Math.min(maxHeight, Math.max(MIN_TERMINAL_HEIGHT, this.#startHeight - deltaY));
773
- this.terminalHeight.set(`${newHeight}px`);
774
- };
775
- #onMouseUp = () => {
776
- this.isDragging.set(false);
777
- document.removeEventListener('mousemove', this.#onMouseMove);
778
- document.removeEventListener('mouseup', this.#onMouseUp);
779
- };
802
+ constructor() {
803
+ this.#thinkingService = inject(ThinkingService);
804
+ this.isThinking = this.#thinkingService.isThinking;
805
+ this.terminalHeight = signal(`${DEFAULT_TERMINAL_HEIGHT}px`, ...(ngDevMode ? [{ debugName: "terminalHeight" }] : /* istanbul ignore next */ []));
806
+ this.isDragging = signal(false, ...(ngDevMode ? [{ debugName: "isDragging" }] : /* istanbul ignore next */ []));
807
+ this.#startY = 0;
808
+ this.#startHeight = DEFAULT_TERMINAL_HEIGHT;
809
+ this.#onMouseMove = (event) => {
810
+ const deltaY = event.clientY - this.#startY;
811
+ const maxHeight = Math.floor(window.innerHeight * MAX_TERMINAL_RATIO);
812
+ const newHeight = Math.min(maxHeight, Math.max(MIN_TERMINAL_HEIGHT, this.#startHeight - deltaY));
813
+ this.terminalHeight.set(`${newHeight}px`);
814
+ };
815
+ this.#onMouseUp = () => {
816
+ this.isDragging.set(false);
817
+ document.removeEventListener('mousemove', this.#onMouseMove);
818
+ document.removeEventListener('mouseup', this.#onMouseUp);
819
+ };
820
+ }
821
+ #thinkingService;
822
+ #startY;
823
+ #startHeight;
824
+ #onMouseMove;
825
+ #onMouseUp;
780
826
  onResizeStart(event) {
781
827
  event.preventDefault();
782
828
  this.#startY = event.clientY;
@@ -785,8 +831,8 @@ class Shell {
785
831
  document.addEventListener('mousemove', this.#onMouseMove);
786
832
  document.addEventListener('mouseup', this.#onMouseUp);
787
833
  }
788
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: Shell, deps: [], target: i0.ɵɵFactoryTarget.Component });
789
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.7", type: Shell, isStandalone: true, selector: "shell-root", ngImport: i0, template: "<div class=\"shell\" [style.--terminal-height]=\"terminalHeight()\" [class.is-dragging]=\"isDragging()\">\n <shell-status-bar class=\"shell-status\" [class.disabled-zone]=\"isThinking()\">\n <ng-content />\n </shell-status-bar>\n <shell-side-menu class=\"shell-menu\" [class.disabled-zone]=\"isThinking()\" />\n <shell-main-content class=\"shell-main\" />\n <div class=\"shell-resize\" [class.dragging]=\"isDragging()\" (mousedown)=\"onResizeStart($event)\"></div>\n <shell-command-terminal class=\"shell-terminal\" [class.disabled-zone]=\"isThinking()\" />\n</div>\n", styles: [".shell{display:grid;grid-template-areas:\"status status\" \"menu main\" \"resize resize\" \"terminal terminal\";grid-template-columns:56px 1fr;grid-template-rows:48px 1fr 4px var(--terminal-height, 160px);height:100vh;width:100vw;overflow:hidden;background-color:var(--color-surface-dark)}.shell-status{grid-area:status}.shell-menu{grid-area:menu}.shell-main{grid-area:main;overflow:hidden}.shell-resize{grid-area:resize;cursor:row-resize;background-color:var(--color-surface-border);transition:background-color .15s ease}.shell-resize:hover,.shell-resize.dragging{background-color:var(--color-interactive)}.shell-terminal{grid-area:terminal}.shell.is-dragging{user-select:none;-webkit-user-select:none}.disabled-zone{pointer-events:none;opacity:.4;transition:opacity .2s ease}\n"], dependencies: [{ kind: "component", type: StatusBar, selector: "shell-status-bar" }, { kind: "component", type: SideMenu, selector: "shell-side-menu" }, { kind: "component", type: MainContent, selector: "shell-main-content" }, { kind: "component", type: CommandTerminal, selector: "shell-command-terminal" }] });
834
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: Shell, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
835
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.7", type: Shell, isStandalone: true, selector: "shell-root", ngImport: i0, template: "<div class=\"shell\" [style.--terminal-height]=\"terminalHeight()\" [class.is-dragging]=\"isDragging()\">\n <shell-status-bar class=\"shell-status\" [class.disabled-zone]=\"isThinking()\">\n <ng-content />\n </shell-status-bar>\n <shell-side-menu class=\"shell-menu\" [class.disabled-zone]=\"isThinking()\" />\n <shell-main-content class=\"shell-main\" />\n <div class=\"shell-resize\" [class.dragging]=\"isDragging()\" (mousedown)=\"onResizeStart($event)\"></div>\n <shell-command-terminal class=\"shell-terminal\" [class.disabled-zone]=\"isThinking()\" />\n</div>\n", styles: [".shell{display:grid;grid-template-areas:\"status status\" \"menu main\" \"resize resize\" \"terminal terminal\";grid-template-columns:56px 1fr;grid-template-rows:48px 1fr 4px var(--terminal-height, 160px);height:100vh;width:100vw;overflow:hidden;background-color:var(--color-surface-dark)}.shell-status{grid-area:status}.shell-menu{grid-area:menu}.shell-main{grid-area:main;overflow:hidden}.shell-resize{grid-area:resize;cursor:row-resize;background-color:var(--color-surface-border);transition:background-color .15s ease}.shell-resize:hover,.shell-resize.dragging{background-color:var(--color-interactive)}.shell-terminal{grid-area:terminal}.shell.is-dragging{user-select:none;-webkit-user-select:none}.disabled-zone{pointer-events:none;opacity:.4;transition:opacity .2s ease}\n"], dependencies: [{ kind: "component", type: StatusBar, selector: "shell-status-bar" }, { kind: "component", type: SideMenu, selector: "shell-side-menu" }, { kind: "component", type: MainContent, selector: "shell-main-content" }, { kind: "component", type: CommandTerminal, selector: "shell-command-terminal" }] }); }
790
836
  }
791
837
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: Shell, decorators: [{
792
838
  type: Component,
@@ -794,20 +840,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImpor
794
840
  }] });
795
841
 
796
842
  class Login {
797
- authenticationService;
798
- router;
799
- model = { username: '', password: '' };
800
- submitted = false;
801
- hide = signal(true, ...(ngDevMode ? [{ debugName: "hide" }] : /* istanbul ignore next */ []));
802
- errors = [];
803
- USERNAME_REGEX = USERNAME_REGEX;
804
- PASSWORD_REGEX = PASSWORD_REGEX;
805
- appName = inject(SHELL_APP_NAME, { optional: true }) ?? 'Application';
806
- #commandService = inject(CommandService);
807
- #terminalFocusService = inject(TerminalFocusService);
843
+ #commandService;
844
+ #terminalFocusService;
808
845
  constructor(authenticationService, router) {
809
846
  this.authenticationService = authenticationService;
810
847
  this.router = router;
848
+ this.model = { username: '', password: '' };
849
+ this.submitted = false;
850
+ this.hide = signal(true, ...(ngDevMode ? [{ debugName: "hide" }] : /* istanbul ignore next */ []));
851
+ this.takeover = signal(true, ...(ngDevMode ? [{ debugName: "takeover" }] : /* istanbul ignore next */ []));
852
+ this.errors = [];
853
+ this.USERNAME_REGEX = USERNAME_REGEX;
854
+ this.PASSWORD_REGEX = PASSWORD_REGEX;
855
+ this.appName = inject(SHELL_APP_NAME, { optional: true }) ?? 'Application';
856
+ this.#commandService = inject(CommandService);
857
+ this.#terminalFocusService = inject(TerminalFocusService);
811
858
  }
812
859
  onAutofill(event, inputEl) {
813
860
  if (event.isAutofilled) {
@@ -827,7 +874,7 @@ class Login {
827
874
  this.submitted = true;
828
875
  const result = validateCredentials(this.model);
829
876
  if (result === true) {
830
- this.#doLogin(false);
877
+ this.#doLogin(this.takeover());
831
878
  }
832
879
  else {
833
880
  for (let ndx = 0; ndx < result.length; ndx++) {
@@ -864,8 +911,8 @@ class Login {
864
911
  this.submitted = false;
865
912
  });
866
913
  }
867
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: Login, deps: [{ token: AuthenticationService }, { token: i2$1.Router }], target: i0.ɵɵFactoryTarget.Component });
868
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.7", type: Login, isStandalone: true, selector: "shell-login", ngImport: i0, template: "@let usernameRegex = USERNAME_REGEX;\n@let passwordRegex = PASSWORD_REGEX;\n<div class=\"login-container\">\n <div class=\"login-header\">\n <h2 class=\"text-text-primary\">{{ appName }}</h2>\n <p class=\"text-secondary-info\">Sign in to continue</p>\n </div>\n <form #loginForm=\"ngForm\" (ngSubmit)=\"onSubmit($event)\" class=\"login-form\">\n <mat-form-field appearance=\"outline\" class=\"login-field\">\n <mat-label>Username</mat-label>\n <input\n #usernameInput\n matInput\n placeholder=\"Enter username\"\n [(ngModel)]=\"model.username\"\n name=\"username\"\n [disabled]=\"submitted\"\n required\n regexValidator\n [regex]=\"usernameRegex\"\n (cdkAutofill)=\"onAutofill($event, usernameInput)\"\n />\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"login-field\">\n <mat-label>Password</mat-label>\n <input\n #passwordInput\n matInput\n placeholder=\"Enter password\"\n [type]=\"hide() ? 'password' : 'text'\"\n [(ngModel)]=\"model.password\"\n name=\"password\"\n [disabled]=\"submitted\"\n regexValidator\n [regex]=\"passwordRegex\"\n (cdkAutofill)=\"onAutofill($event, passwordInput)\"\n />\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n (click)=\"clickEvent($event)\"\n [attr.aria-label]=\"'Hide password'\"\n [attr.aria-pressed]=\"hide()\"\n >\n <mat-icon>{{ hide() ? 'visibility_off' : 'visibility' }}</mat-icon>\n </button>\n </mat-form-field>\n <button mat-flat-button type=\"submit\" [disabled]=\"submitted\" class=\"login-button\">\n Login\n </button>\n </form>\n @if (errors.length > 0) {\n <div class=\"login-errors\">\n @for (error of errors; track error.ndx) {\n <div class=\"login-error text-loss\">{{ error.message }}</div>\n }\n </div>\n }\n @if (authenticationService.conflictSessions(); as sessions) {\n <div class=\"login-conflict\">\n @for (session of sessions; track $index) {\n <p class=\"text-secondary-info\">\n Already logged in from <strong>{{ session.appContext }}</strong>\n since {{ session.startEpoch | date:'short' }}.\n </p>\n }\n <p class=\"text-secondary-info\">Log in here and end that session?</p>\n <div class=\"login-conflict-actions\">\n <button mat-stroked-button type=\"button\" (click)=\"onCancelConflict()\">Cancel</button>\n <button mat-flat-button type=\"button\" (click)=\"onTakeOver()\">Take Over</button>\n </div>\n </div>\n }\n</div>\n", styles: [".login-container{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;text-align:center}.login-header{margin-bottom:32px}.login-header h2{font-size:1.5rem;font-weight:300;margin-bottom:8px}.login-form{display:flex;flex-direction:column;align-items:center;gap:8px;width:320px}.login-field{width:100%;text-align:left}.login-button{margin-top:8px;width:100%}.login-errors{margin-top:16px;max-width:320px}.login-conflict{margin-top:16px;max-width:320px;padding:12px 16px;border-radius:4px;background-color:var(--color-surface-light);font-size:.85rem;text-align:left}.login-conflict p{margin:0 0 8px}.login-conflict-actions{display:flex;gap:8px;margin-top:12px;justify-content:flex-end}.login-error{padding:8px 12px;margin-bottom:4px;font-size:.85rem;border-radius:4px;background-color:var(--color-surface-light)}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3.NgForm, selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i5.CdkAutofill, selector: "[cdkAutofill]", outputs: ["cdkAutofill"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i6.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i6.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: RegexValidatorDirective, selector: "[regexValidator]", inputs: ["regex"] }, { kind: "ngmodule", type: TextFieldModule }, { kind: "pipe", type: DatePipe, name: "date" }] });
914
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: Login, deps: [{ token: AuthenticationService }, { token: i2$1.Router }], target: i0.ɵɵFactoryTarget.Component }); }
915
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.7", type: Login, isStandalone: true, selector: "shell-login", ngImport: i0, template: "@let usernameRegex = USERNAME_REGEX;\n@let passwordRegex = PASSWORD_REGEX;\n<div class=\"login-container\">\n <div class=\"login-header\">\n <h2 class=\"text-text-primary\">{{ appName }}</h2>\n <p class=\"text-secondary-info\">Sign in to continue</p>\n </div>\n <form #loginForm=\"ngForm\" (ngSubmit)=\"onSubmit($event)\" class=\"login-form\">\n <mat-form-field appearance=\"outline\" class=\"login-field\">\n <mat-label>Username</mat-label>\n <input\n #usernameInput\n matInput\n placeholder=\"Enter username\"\n [(ngModel)]=\"model.username\"\n name=\"username\"\n [disabled]=\"submitted\"\n required\n regexValidator\n [regex]=\"usernameRegex\"\n (cdkAutofill)=\"onAutofill($event, usernameInput)\"\n />\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"login-field\">\n <mat-label>Password</mat-label>\n <input\n #passwordInput\n matInput\n placeholder=\"Enter password\"\n [type]=\"hide() ? 'password' : 'text'\"\n [(ngModel)]=\"model.password\"\n name=\"password\"\n [disabled]=\"submitted\"\n regexValidator\n [regex]=\"passwordRegex\"\n (cdkAutofill)=\"onAutofill($event, passwordInput)\"\n />\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n (click)=\"clickEvent($event)\"\n [attr.aria-label]=\"'Hide password'\"\n [attr.aria-pressed]=\"hide()\"\n >\n <mat-icon>{{ hide() ? 'visibility_off' : 'visibility' }}</mat-icon>\n </button>\n </mat-form-field>\n <mat-checkbox\n class=\"login-takeover\"\n name=\"takeover\"\n [checked]=\"takeover()\"\n (change)=\"takeover.set($event.checked)\"\n [disabled]=\"submitted\"\n >\n Takeover session if logged in elsewhere\n </mat-checkbox>\n <button mat-flat-button type=\"submit\" [disabled]=\"submitted\" class=\"login-button\">\n Login\n </button>\n </form>\n @if (errors.length > 0) {\n <div class=\"login-errors\">\n @for (error of errors; track error.ndx) {\n <div class=\"login-error text-loss\">{{ error.message }}</div>\n }\n </div>\n }\n @if (authenticationService.conflictSessions(); as sessions) {\n <div class=\"login-conflict\">\n @for (session of sessions; track $index) {\n <p class=\"text-secondary-info\">\n Already logged in from <strong>{{ session.appContext }}</strong>\n since {{ session.startEpoch | date:'short' }}.\n </p>\n }\n <p class=\"text-secondary-info\">Log in here and end that session?</p>\n <div class=\"login-conflict-actions\">\n <button mat-stroked-button type=\"button\" (click)=\"onCancelConflict()\">Cancel</button>\n <button mat-flat-button type=\"button\" (click)=\"onTakeOver()\">Take Over</button>\n </div>\n </div>\n }\n</div>\n", styles: [".login-container{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;text-align:center}.login-header{margin-bottom:32px}.login-header h2{font-size:1.5rem;font-weight:300;margin-bottom:8px}.login-form{display:flex;flex-direction:column;align-items:center;gap:8px;width:320px}.login-field{width:100%;text-align:left}.login-takeover{align-self:flex-start;margin-top:4px}.login-button{margin-top:8px;width:100%}.login-errors{margin-top:16px;max-width:320px}.login-conflict{margin-top:16px;max-width:320px;padding:12px 16px;border-radius:4px;background-color:var(--color-surface-light);font-size:.85rem;text-align:left}.login-conflict p{margin:0 0 8px}.login-conflict-actions{display:flex;gap:8px;margin-top:12px;justify-content:flex-end}.login-error{padding:8px 12px;margin-bottom:4px;font-size:.85rem;border-radius:4px;background-color:var(--color-surface-light)}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3.NgForm, selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i5.CdkAutofill, selector: "[cdkAutofill]", outputs: ["cdkAutofill"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i6.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i6.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i7.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: RegexValidatorDirective, selector: "[regexValidator]", inputs: ["regex"] }, { kind: "ngmodule", type: TextFieldModule }, { kind: "pipe", type: DatePipe, name: "date" }] }); }
869
916
  }
870
917
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: Login, decorators: [{
871
918
  type: Component,
@@ -876,18 +923,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImpor
876
923
  MatInput,
877
924
  MatInputModule,
878
925
  MatButtonModule,
926
+ MatCheckboxModule,
879
927
  MatIconModule,
880
928
  RegexValidatorDirective,
881
929
  TextFieldModule,
882
930
  DatePipe,
883
- ], template: "@let usernameRegex = USERNAME_REGEX;\n@let passwordRegex = PASSWORD_REGEX;\n<div class=\"login-container\">\n <div class=\"login-header\">\n <h2 class=\"text-text-primary\">{{ appName }}</h2>\n <p class=\"text-secondary-info\">Sign in to continue</p>\n </div>\n <form #loginForm=\"ngForm\" (ngSubmit)=\"onSubmit($event)\" class=\"login-form\">\n <mat-form-field appearance=\"outline\" class=\"login-field\">\n <mat-label>Username</mat-label>\n <input\n #usernameInput\n matInput\n placeholder=\"Enter username\"\n [(ngModel)]=\"model.username\"\n name=\"username\"\n [disabled]=\"submitted\"\n required\n regexValidator\n [regex]=\"usernameRegex\"\n (cdkAutofill)=\"onAutofill($event, usernameInput)\"\n />\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"login-field\">\n <mat-label>Password</mat-label>\n <input\n #passwordInput\n matInput\n placeholder=\"Enter password\"\n [type]=\"hide() ? 'password' : 'text'\"\n [(ngModel)]=\"model.password\"\n name=\"password\"\n [disabled]=\"submitted\"\n regexValidator\n [regex]=\"passwordRegex\"\n (cdkAutofill)=\"onAutofill($event, passwordInput)\"\n />\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n (click)=\"clickEvent($event)\"\n [attr.aria-label]=\"'Hide password'\"\n [attr.aria-pressed]=\"hide()\"\n >\n <mat-icon>{{ hide() ? 'visibility_off' : 'visibility' }}</mat-icon>\n </button>\n </mat-form-field>\n <button mat-flat-button type=\"submit\" [disabled]=\"submitted\" class=\"login-button\">\n Login\n </button>\n </form>\n @if (errors.length > 0) {\n <div class=\"login-errors\">\n @for (error of errors; track error.ndx) {\n <div class=\"login-error text-loss\">{{ error.message }}</div>\n }\n </div>\n }\n @if (authenticationService.conflictSessions(); as sessions) {\n <div class=\"login-conflict\">\n @for (session of sessions; track $index) {\n <p class=\"text-secondary-info\">\n Already logged in from <strong>{{ session.appContext }}</strong>\n since {{ session.startEpoch | date:'short' }}.\n </p>\n }\n <p class=\"text-secondary-info\">Log in here and end that session?</p>\n <div class=\"login-conflict-actions\">\n <button mat-stroked-button type=\"button\" (click)=\"onCancelConflict()\">Cancel</button>\n <button mat-flat-button type=\"button\" (click)=\"onTakeOver()\">Take Over</button>\n </div>\n </div>\n }\n</div>\n", styles: [".login-container{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;text-align:center}.login-header{margin-bottom:32px}.login-header h2{font-size:1.5rem;font-weight:300;margin-bottom:8px}.login-form{display:flex;flex-direction:column;align-items:center;gap:8px;width:320px}.login-field{width:100%;text-align:left}.login-button{margin-top:8px;width:100%}.login-errors{margin-top:16px;max-width:320px}.login-conflict{margin-top:16px;max-width:320px;padding:12px 16px;border-radius:4px;background-color:var(--color-surface-light);font-size:.85rem;text-align:left}.login-conflict p{margin:0 0 8px}.login-conflict-actions{display:flex;gap:8px;margin-top:12px;justify-content:flex-end}.login-error{padding:8px 12px;margin-bottom:4px;font-size:.85rem;border-radius:4px;background-color:var(--color-surface-light)}\n"] }]
931
+ ], template: "@let usernameRegex = USERNAME_REGEX;\n@let passwordRegex = PASSWORD_REGEX;\n<div class=\"login-container\">\n <div class=\"login-header\">\n <h2 class=\"text-text-primary\">{{ appName }}</h2>\n <p class=\"text-secondary-info\">Sign in to continue</p>\n </div>\n <form #loginForm=\"ngForm\" (ngSubmit)=\"onSubmit($event)\" class=\"login-form\">\n <mat-form-field appearance=\"outline\" class=\"login-field\">\n <mat-label>Username</mat-label>\n <input\n #usernameInput\n matInput\n placeholder=\"Enter username\"\n [(ngModel)]=\"model.username\"\n name=\"username\"\n [disabled]=\"submitted\"\n required\n regexValidator\n [regex]=\"usernameRegex\"\n (cdkAutofill)=\"onAutofill($event, usernameInput)\"\n />\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"login-field\">\n <mat-label>Password</mat-label>\n <input\n #passwordInput\n matInput\n placeholder=\"Enter password\"\n [type]=\"hide() ? 'password' : 'text'\"\n [(ngModel)]=\"model.password\"\n name=\"password\"\n [disabled]=\"submitted\"\n regexValidator\n [regex]=\"passwordRegex\"\n (cdkAutofill)=\"onAutofill($event, passwordInput)\"\n />\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n (click)=\"clickEvent($event)\"\n [attr.aria-label]=\"'Hide password'\"\n [attr.aria-pressed]=\"hide()\"\n >\n <mat-icon>{{ hide() ? 'visibility_off' : 'visibility' }}</mat-icon>\n </button>\n </mat-form-field>\n <mat-checkbox\n class=\"login-takeover\"\n name=\"takeover\"\n [checked]=\"takeover()\"\n (change)=\"takeover.set($event.checked)\"\n [disabled]=\"submitted\"\n >\n Takeover session if logged in elsewhere\n </mat-checkbox>\n <button mat-flat-button type=\"submit\" [disabled]=\"submitted\" class=\"login-button\">\n Login\n </button>\n </form>\n @if (errors.length > 0) {\n <div class=\"login-errors\">\n @for (error of errors; track error.ndx) {\n <div class=\"login-error text-loss\">{{ error.message }}</div>\n }\n </div>\n }\n @if (authenticationService.conflictSessions(); as sessions) {\n <div class=\"login-conflict\">\n @for (session of sessions; track $index) {\n <p class=\"text-secondary-info\">\n Already logged in from <strong>{{ session.appContext }}</strong>\n since {{ session.startEpoch | date:'short' }}.\n </p>\n }\n <p class=\"text-secondary-info\">Log in here and end that session?</p>\n <div class=\"login-conflict-actions\">\n <button mat-stroked-button type=\"button\" (click)=\"onCancelConflict()\">Cancel</button>\n <button mat-flat-button type=\"button\" (click)=\"onTakeOver()\">Take Over</button>\n </div>\n </div>\n }\n</div>\n", styles: [".login-container{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;text-align:center}.login-header{margin-bottom:32px}.login-header h2{font-size:1.5rem;font-weight:300;margin-bottom:8px}.login-form{display:flex;flex-direction:column;align-items:center;gap:8px;width:320px}.login-field{width:100%;text-align:left}.login-takeover{align-self:flex-start;margin-top:4px}.login-button{margin-top:8px;width:100%}.login-errors{margin-top:16px;max-width:320px}.login-conflict{margin-top:16px;max-width:320px;padding:12px 16px;border-radius:4px;background-color:var(--color-surface-light);font-size:.85rem;text-align:left}.login-conflict p{margin:0 0 8px}.login-conflict-actions{display:flex;gap:8px;margin-top:12px;justify-content:flex-end}.login-error{padding:8px 12px;margin-bottom:4px;font-size:.85rem;border-radius:4px;background-color:var(--color-surface-light)}\n"] }]
884
932
  }], ctorParameters: () => [{ type: AuthenticationService }, { type: i2$1.Router }] });
885
933
 
886
934
  class ConfirmDialog {
887
- data = inject(MAT_DIALOG_DATA);
888
- dialogRef = inject((MatDialogRef));
889
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: ConfirmDialog, deps: [], target: i0.ɵɵFactoryTarget.Component });
890
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.7", type: ConfirmDialog, isStandalone: true, selector: "shell-confirm-dialog", ngImport: i0, template: `
935
+ constructor() {
936
+ this.data = inject(MAT_DIALOG_DATA);
937
+ this.dialogRef = inject((MatDialogRef));
938
+ }
939
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: ConfirmDialog, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
940
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.7", type: ConfirmDialog, isStandalone: true, selector: "shell-confirm-dialog", ngImport: i0, template: `
891
941
  <h2 mat-dialog-title>{{ data.title }}</h2>
892
942
  <mat-dialog-content>
893
943
  <p>{{ data.message }}</p>
@@ -899,7 +949,7 @@ class ConfirmDialog {
899
949
  <button mat-button (click)="dialogRef.close(false)">{{ data.cancelLabel ?? 'Cancel' }}</button>
900
950
  <button mat-flat-button color="warn" (click)="dialogRef.close(true)">{{ data.confirmLabel ?? 'Confirm' }}</button>
901
951
  </mat-dialog-actions>
902
- `, isInline: true, styles: [":host{display:block}.warning-message{color:var(--color-warning);margin-top:8px}\n"], dependencies: [{ kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1$2.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1$2.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1$2.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i6.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }] });
952
+ `, isInline: true, styles: [":host{display:block}.warning-message{color:var(--color-warning);margin-top:8px}\n"], dependencies: [{ kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1$2.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1$2.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1$2.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i6.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }] }); }
903
953
  }
904
954
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: ConfirmDialog, decorators: [{
905
955
  type: Component,
@@ -1 +1 @@
1
- {"version":3,"file":"franzzemen-brokenstock-shell.mjs","sources":["../../src/lib/tokens/shell-tokens.ts","../../src/lib/provide-shell-config.ts","../../src/lib/services/thinking.service.ts","../../src/lib/services/authentication.service.ts","../../src/lib/guards/auth.guard.ts","../../src/lib/interceptors/auth.interceptor.ts","../../src/lib/directives/regex-validator.directive.ts","../../src/lib/services/theme.service.ts","../../src/lib/services/terminal-focus.service.ts","../../src/lib/services/keyboard-shortcut.service.ts","../../src/lib/services/command-registry.service.ts","../../src/lib/commands/command.utils.ts","../../src/lib/services/command.service.ts","../../src/lib/components/status-bar/status-bar.ts","../../src/lib/components/status-bar/status-bar.html","../../src/lib/components/side-menu/side-menu.ts","../../src/lib/components/side-menu/side-menu.html","../../src/lib/components/main-content/main-content.ts","../../src/lib/components/main-content/main-content.html","../../src/lib/components/command-terminal/command-terminal.ts","../../src/lib/components/command-terminal/command-terminal.html","../../src/lib/components/shell/shell.ts","../../src/lib/components/shell/shell.html","../../src/lib/components/login/login.ts","../../src/lib/components/login/login.html","../../src/lib/components/confirm-dialog/confirm-dialog.ts","../../src/public-api.ts","../../src/franzzemen-brokenstock-shell.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\nimport { CommandDefinition } from '../types/command.types';\nimport { MenuItem } from '../types/menu.types';\n\nexport interface ShellAuthUrls {\n login: string;\n logout: string;\n refresh: string;\n}\n\nexport const SHELL_APP_NAME = new InjectionToken<string>('SHELL_APP_NAME');\nexport const SHELL_MENU_ITEMS = new InjectionToken<MenuItem[]>('SHELL_MENU_ITEMS');\nexport const SHELL_AUTH_URLS = new InjectionToken<ShellAuthUrls>('SHELL_AUTH_URLS');\n\n/**\n * App-specific commands to register alongside the built-in command set.\n * Provide via provideShellConfig().\n */\nexport const SHELL_COMMANDS = new InjectionToken<CommandDefinition[]>('SHELL_COMMANDS');\n","import { EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\nimport { CommandDefinition } from './types/command.types';\nimport { MenuItem } from './types/menu.types';\nimport { SHELL_APP_NAME, SHELL_AUTH_URLS, SHELL_COMMANDS, SHELL_MENU_ITEMS, ShellAuthUrls } from './tokens/shell-tokens';\n\nexport interface ShellConfig {\n appName: string;\n menuItems: MenuItem[];\n authUrls: ShellAuthUrls;\n commands?: CommandDefinition[];\n}\n\nexport function provideShellConfig(config: ShellConfig): EnvironmentProviders {\n return makeEnvironmentProviders([\n { provide: SHELL_APP_NAME, useValue: config.appName },\n { provide: SHELL_MENU_ITEMS, useValue: config.menuItems },\n { provide: SHELL_AUTH_URLS, useValue: config.authUrls },\n { provide: SHELL_COMMANDS, useValue: config.commands ?? [] },\n ]);\n}\n","import { Injectable, signal, computed } from '@angular/core';\n\n@Injectable({ providedIn: 'root' })\nexport class ThinkingService {\n readonly #activeCount = signal(0);\n\n readonly isThinking = computed(() => this.#activeCount() > 0);\n\n startThinking(): void {\n this.#activeCount.update(c => c + 1);\n }\n\n stopThinking(): void {\n this.#activeCount.update(c => Math.max(0, c - 1));\n }\n\n reset(): void {\n this.#activeCount.set(0);\n }\n}\n","import { computed, inject, Injectable, signal } from '@angular/core';\nimport { BEARER_TOKEN_REGEX, BearerToken, HttpHeader } from '@franzzemen/utility';\nimport { AuthenticationResponse, Credentials, EffectivePermissions, RoleNames, SessionSummary, UserSession, validateCredentials } from '@franzzemen/identity';\nimport { HttpClient, HttpErrorResponse, HttpResponse } from '@angular/common/http';\nimport { Router } from '@angular/router';\nimport { ThinkingService } from './thinking.service';\nimport { SHELL_AUTH_URLS } from '../tokens/shell-tokens';\n\n@Injectable({ providedIn: 'root' })\nexport class AuthenticationService {\n readonly authenticated = signal(false);\n readonly authenticating = signal(false);\n readonly userSession = signal<UserSession | undefined>(undefined);\n readonly effectivePermissions = signal<EffectivePermissions>({});\n readonly conflictSessions = signal<SessionSummary[] | undefined>(undefined);\n\n #refreshing: Promise<boolean> | null = null;\n #auth: BearerToken = 'Bearer ..' as BearerToken;\n\n readonly #httpClient = inject(HttpClient);\n readonly #thinkingService = inject(ThinkingService);\n readonly #router = inject(Router);\n readonly #authUrls = inject(SHELL_AUTH_URLS);\n\n get auth(): BearerToken {\n return this.#auth;\n }\n\n /** Check if the current user has a specific role. */\n hasRole(roleName: RoleNames): boolean {\n return this.authenticated() && this.userSession()?.roles.includes(roleName) === true;\n }\n\n /** Check if the current user has any of the specified roles. */\n hasAnyRole(roleNames: RoleNames[]): boolean {\n return this.authenticated() && roleNames.some(r => this.userSession()?.roles.includes(r) === true);\n }\n\n refresh(): Promise<boolean> {\n if (this.#refreshing) {\n return this.#refreshing;\n }\n this.#refreshing = this.#doRefresh().finally(() => { this.#refreshing = null; });\n return this.#refreshing;\n }\n\n logout(): void {\n const subscription = this.#httpClient\n .get<void>(this.#authUrls.logout, {\n headers: {\n [HttpHeader.Authorization]: this.#auth,\n [HttpHeader.AppContext]: 'brokenstock',\n },\n })\n .subscribe({\n next: () => {\n this.#clearSession();\n subscription.unsubscribe();\n },\n error: () => {\n this.#thinkingService.reset();\n this.#clearSession();\n },\n });\n }\n\n login(credentials: Credentials, force = false): Promise<void> {\n const validation = validateCredentials(credentials);\n if (validation !== true) {\n return Promise.reject('Invalid credentials');\n }\n this.conflictSessions.set(undefined);\n this.#thinkingService.startThinking();\n return new Promise((resolve, reject) => {\n this.authenticating.set(true);\n const body = force ? {...credentials, force: true} : credentials;\n const subscription = this.#httpClient\n .post<HttpResponse<AuthenticationResponse>>(\n this.#authUrls.login,\n body,\n {\n headers: {\n [HttpHeader.ContentType]: 'application/json',\n [HttpHeader.AppContext]: 'brokenstock',\n },\n observe: 'response',\n responseType: 'json',\n withCredentials: true,\n },\n )\n .subscribe({\n next: (response: HttpResponse<any>) => {\n try {\n const authResponse: AuthenticationResponse = response.body;\n // @ts-ignore\n delete authResponse.session.token;\n this.userSession.set(authResponse.session);\n this.effectivePermissions.set(authResponse.effectivePermissions ?? {});\n const auth = response.headers.get(HttpHeader.Authorization);\n if (!auth || !BEARER_TOKEN_REGEX.test(auth)) {\n reject('Unable to login');\n return;\n }\n this.#auth = auth as BearerToken;\n this.authenticated.set(true);\n resolve();\n } catch {\n reject('Unable to login');\n } finally {\n this.authenticating.set(false);\n subscription.unsubscribe();\n this.#thinkingService.stopThinking();\n }\n },\n error: (err: HttpErrorResponse) => {\n try {\n if (err.status === 409) {\n this.conflictSessions.set(err.error?.activeSessions ?? []);\n reject('conflict');\n } else {\n reject(err.message ?? 'Unable to login');\n }\n } finally {\n this.authenticating.set(false);\n subscription.unsubscribe();\n this.#thinkingService.stopThinking();\n }\n },\n });\n });\n }\n\n async #doRefresh(): Promise<boolean> {\n try {\n const response = await fetch(this.#authUrls.refresh, {\n method: 'POST',\n headers: {\n [HttpHeader.Authorization]: this.#auth,\n [HttpHeader.AppContext]: 'brokenstock',\n },\n credentials: 'include',\n });\n if (!response.ok) return false;\n const auth = response.headers.get(HttpHeader.Authorization);\n if (!auth || !BEARER_TOKEN_REGEX.test(auth)) return false;\n const body: AuthenticationResponse = await response.json();\n this.#auth = auth as BearerToken;\n this.userSession.set(body.session);\n this.effectivePermissions.set(body.effectivePermissions ?? {});\n return true;\n } catch {\n return false;\n }\n }\n\n #clearSession(): void {\n this.authenticated.set(false);\n this.userSession.set(undefined);\n this.effectivePermissions.set({});\n this.conflictSessions.set(undefined);\n this.#auth = 'Bearer ..' as BearerToken;\n this.#router.navigate(['/login']).catch(console.error);\n }\n}\n","import { inject } from '@angular/core';\nimport { CanActivateFn, Router } from '@angular/router';\nimport { AuthenticationService } from '../services/authentication.service';\n\nexport const authGuard: CanActivateFn = () => {\n const authService = inject(AuthenticationService);\n const router = inject(Router);\n\n if (authService.authenticated()) {\n return true;\n }\n return router.createUrlTree(['/login']);\n};\n","import { HttpInterceptorFn } from '@angular/common/http';\nimport { inject } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { from, switchMap, catchError, tap, throwError } from 'rxjs';\nimport { AuthenticationService } from '../services/authentication.service';\nimport { ThinkingService } from '../services/thinking.service';\nimport { SHELL_AUTH_URLS } from '../tokens/shell-tokens';\nimport { HttpHeader } from '@franzzemen/utility';\n\nexport const authInterceptor: HttpInterceptorFn = (req, next) => {\n const authService = inject(AuthenticationService);\n const thinkingService = inject(ThinkingService);\n const authUrls = inject(SHELL_AUTH_URLS);\n const router = inject(Router);\n\n return next(req).pipe(\n tap({\n next: (event) => {\n if ('headers' in event && event.headers?.get('x-permissions-stale') === 'true') {\n authService.refresh();\n }\n },\n }),\n catchError((error) => {\n const isRefreshOrLogin = req.url === authUrls.refresh || req.url === authUrls.login;\n if (error.status === 401 && !isRefreshOrLogin) {\n return from(authService.refresh()).pipe(\n switchMap((refreshed) => {\n if (refreshed) {\n const retryReq = req.clone({\n setHeaders: { [HttpHeader.Authorization]: authService.auth },\n });\n return next(retryReq);\n }\n thinkingService.reset();\n authService.authenticated.set(false);\n authService.userSession.set(undefined);\n router.navigate(['/login']);\n return throwError(() => error);\n }),\n catchError(() => {\n thinkingService.reset();\n authService.authenticated.set(false);\n authService.userSession.set(undefined);\n router.navigate(['/login']);\n return throwError(() => error);\n }),\n );\n }\n return throwError(() => error);\n }),\n );\n};\n","import { Directive, input } from '@angular/core';\nimport { AbstractControl, NG_VALIDATORS, ValidationErrors, Validator } from '@angular/forms';\n\n@Directive({\n selector: '[regexValidator]',\n providers: [{ provide: NG_VALIDATORS, useExisting: RegexValidatorDirective, multi: true }],\n})\nexport class RegexValidatorDirective implements Validator {\n regex = input(/^[A-Z0-9._%+-@!?]{4,64}$/i);\n\n validate(control: AbstractControl): ValidationErrors | null {\n if (!control.value || !this.regex().test(control.value)) {\n return { regexValidator: { value: control.value } };\n }\n return null;\n }\n}\n","import { Injectable, signal, computed } from '@angular/core';\n\nexport type ThemeMode = 'dark';\n\n@Injectable({ providedIn: 'root' })\nexport class ThemeService {\n readonly mode = signal<ThemeMode>('dark');\n readonly isDark = computed(() => this.mode() === 'dark');\n}\n","import { Injectable, signal } from '@angular/core';\n\n@Injectable({ providedIn: 'root' })\nexport class TerminalFocusService {\n readonly focusRequested = signal(0);\n\n requestFocus(): void {\n this.focusRequested.update(v => v + 1);\n }\n}\n","import { computed, inject, Injectable, NgZone, signal } from '@angular/core';\nimport { DOCUMENT } from '@angular/common';\nimport { TerminalFocusService } from './terminal-focus.service';\n\nexport interface ShortcutRegistration {\n key: string;\n modifier?: 'Alt';\n action: () => void;\n description: string;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class KeyboardShortcutService {\n readonly #groups = new Map<string, ShortcutRegistration[]>();\n readonly #activeGroupId = signal<string | null>(null);\n\n readonly #document = inject(DOCUMENT);\n readonly #zone = inject(NgZone);\n readonly #focusService = inject(TerminalFocusService);\n\n readonly helpVisible = signal(false);\n\n readonly activeShortcuts = computed(() => {\n const groupId = this.#activeGroupId();\n if (!groupId) return null;\n const shortcuts = this.#groups.get(groupId);\n if (!shortcuts) return null;\n return { groupId, shortcuts };\n });\n\n constructor() {\n this.#zone.runOutsideAngular(() => {\n this.#document.addEventListener('keydown', (event: KeyboardEvent) => {\n this.#handleKeydown(event);\n });\n });\n }\n\n registerGroup(groupId: string, shortcuts: ShortcutRegistration[]): void {\n this.#groups.set(groupId, shortcuts);\n this.#activeGroupId.set(groupId);\n }\n\n unregisterGroup(groupId: string): void {\n this.#groups.delete(groupId);\n if (this.#activeGroupId() === groupId) {\n const keys = [...this.#groups.keys()];\n this.#activeGroupId.set(keys.length > 0 ? keys[keys.length - 1] : null);\n }\n }\n\n toggleHelp(): void {\n this.helpVisible.update(v => !v);\n }\n\n #handleKeydown(event: KeyboardEvent): boolean {\n const activeId = this.#activeGroupId();\n if (activeId) {\n const shortcuts = this.#groups.get(activeId);\n if (shortcuts) {\n const match = shortcuts.find(s => {\n if (s.modifier === 'Alt') return event.altKey && s.key === event.key;\n return !event.altKey && !event.ctrlKey && !event.metaKey && s.key === event.key;\n });\n if (match) {\n event.preventDefault();\n this.#zone.run(() => match.action());\n return true;\n }\n }\n }\n\n if (event.key === 'Escape') {\n event.preventDefault();\n this.#zone.run(() => {\n this.helpVisible.set(false);\n this.#focusService.requestFocus();\n });\n return true;\n }\n\n if (!event.altKey) return false;\n\n if (event.key === '?' || event.key === '/') {\n event.preventDefault();\n this.#zone.run(() => this.toggleHelp());\n return true;\n }\n\n return false;\n }\n}\n","import { inject, Injectable } from '@angular/core';\nimport { CommandDefinition } from '../types/command.types';\nimport { SHELL_COMMANDS } from '../tokens/shell-tokens';\n\n@Injectable({ providedIn: 'root' })\nexport class CommandRegistryService {\n private readonly commands = new Map<string, CommandDefinition>();\n\n constructor() {\n const appCommands = inject(SHELL_COMMANDS, { optional: true }) ?? [];\n for (const cmd of appCommands) {\n this.register(cmd);\n }\n }\n\n register(command: CommandDefinition): void {\n this.commands.set(command.name, command);\n }\n\n get(name: string): CommandDefinition | undefined {\n return this.commands.get(name);\n }\n\n getAll(): CommandDefinition[] {\n return Array.from(this.commands.values());\n }\n\n /**\n * Returns command name suggestions for tab-completion.\n * Built-ins (clear, help) are included when authenticated.\n */\n getSuggestions(prefix: string, isAuthenticated: boolean): string[] {\n if (!prefix) return [];\n if (!isAuthenticated) {\n return 'login'.startsWith(prefix) && 'login' !== prefix ? ['login'] : [];\n }\n const builtIns = ['clear', 'help'];\n const registered = [...this.commands.values()].map(c => c.name);\n return [...builtIns, ...registered]\n .filter(name => name.startsWith(prefix) && name !== prefix)\n .sort();\n }\n}\n","/**\n * Quote-aware command tokenizer. Treats \"...\" as single tokens and strips enclosing quotes.\n */\nexport function tokenize(input: string): string[] {\n return (input.match(/(?:\"[^\"]*\"|\\S)+/g) ?? []).map(t => t.replace(/\"([^\"]*)\"/g, '$1'));\n}\n\nexport const CLEAR_USAGE =\n 'clear\\n\\n' +\n ' Clears the terminal history.\\n' +\n ' No arguments required.';\n\nexport const HELP_USAGE =\n 'help [command]\\n\\n' +\n ' With no arguments, lists all available commands.\\n' +\n ' With a command name, shows detailed usage for that command.\\n\\n' +\n ' Arguments:\\n' +\n ' [command] Optional command name to show detailed help for';\n","import { inject, Injectable, signal, computed, effect } from '@angular/core';\nimport { z } from 'zod/v4';\nimport { CommandResult, CommandHistoryEntry, Severity } from '../types/command.types';\nimport { tokenize, CLEAR_USAGE, HELP_USAGE } from '../commands/command.utils';\nimport { CommandRegistryService } from './command-registry.service';\nimport { AuthenticationService } from './authentication.service';\n\nexport type { CommandResult, CommandHistoryEntry, Severity };\n\nconst CommandInputSchema = z.string().trim().min(1, 'Command cannot be empty');\n\n@Injectable({ providedIn: 'root' })\nexport class CommandService {\n readonly history = signal<CommandHistoryEntry[]>([]);\n readonly currentInput = signal('');\n readonly isProcessing = signal(false);\n\n private readonly authService = inject(AuthenticationService);\n private readonly registry = inject(CommandRegistryService);\n\n constructor() {\n effect(() => {\n if (!this.authService.authenticated()) {\n this.history.set([]);\n }\n });\n }\n\n readonly lastResult = computed(() => {\n const h = this.history();\n return h.length > 0 ? h[h.length - 1].result : null;\n });\n\n echoCommand(input: string): void {\n if (this.#coalesce(input)) return;\n this.history.update(h => [...h, {\n input,\n result: { success: true, message: '', timestamp: new Date() },\n repeatCount: 1,\n }]);\n }\n\n pushNotification(notification: { message: string; severity: Severity }): void {\n this.history.update(h => [...h, {\n input: '',\n result: {\n success: notification.severity !== 'error',\n message: notification.message,\n timestamp: new Date(),\n severity: notification.severity,\n },\n }]);\n }\n\n execute(rawInput: string): void {\n const validation = CommandInputSchema.safeParse(rawInput);\n if (!validation.success) {\n this.history.update(h => [...h, {\n input: rawInput,\n result: { success: false, message: validation.error.issues[0].message, timestamp: new Date() },\n }]);\n this.currentInput.set('');\n return;\n }\n\n const input = validation.data;\n const parts = tokenize(input);\n const command = parts[0].toLowerCase();\n\n const def = this.registry.get(command);\n const displayInput = def?.sanitizeInput ? def.sanitizeInput(input) : input;\n\n const resultOrPromise = this.#dispatch(command, parts.slice(1));\n this.currentInput.set('');\n\n if (resultOrPromise instanceof Promise) {\n this.isProcessing.set(true);\n resultOrPromise\n .then(result => {\n if (!this.#coalesce(displayInput)) {\n this.history.update(h => [...h, { input: displayInput, result, repeatCount: 1 }]);\n }\n })\n .finally(() => this.isProcessing.set(false));\n } else {\n if (!this.#coalesce(displayInput)) {\n this.history.update(h => [...h, { input: displayInput, result: resultOrPromise, repeatCount: 1 }]);\n }\n }\n }\n\n #coalesce(input: string): boolean {\n if (!input) return false;\n const h = this.history();\n for (let i = h.length - 1; i >= 0; i--) {\n if (h[i].input) {\n if (h[i].input === input) {\n this.history.update(history => {\n const updated = [...history];\n updated[i] = { ...updated[i], repeatCount: (updated[i].repeatCount ?? 1) + 1 };\n return updated;\n });\n return true;\n }\n return false;\n }\n }\n return false;\n }\n\n #dispatch(command: string, args: string[]): CommandResult | Promise<CommandResult> {\n const hasHelp = args.some(a => a.toLowerCase() === 'help');\n const isAuthenticated = this.authService.authenticated();\n\n if (!isAuthenticated && command !== 'login') {\n return { success: false, message: 'Not logged in. Use \"login\" to authenticate.', timestamp: new Date() };\n }\n\n if (command === 'clear') {\n if (hasHelp) return { success: true, message: CLEAR_USAGE, timestamp: new Date() };\n this.history.set([]);\n return { success: true, message: '', timestamp: new Date() };\n }\n\n if (command === 'help') {\n const target = args[0]?.toLowerCase();\n if (target) return this.#commandHelp(target);\n const registered = this.registry.getAll();\n const lines = [\n ' clear — Clear terminal history',\n ' help — List available commands',\n ...registered.map(c => ` ${c.name} — ${c.description}`),\n ];\n return {\n success: true,\n message: 'Available commands:\\n' + lines.join('\\n') + '\\n\\nType \"help <command>\" or \"<command> help\" for detailed usage.',\n timestamp: new Date(),\n };\n }\n\n const def = this.registry.get(command);\n if (!def) {\n return { success: false, message: `Unknown command: ${command}`, timestamp: new Date() };\n }\n\n if (hasHelp) {\n return { success: true, message: def.usage, timestamp: new Date() };\n }\n\n const validation = def.argsSchema.safeParse(args);\n if (!validation.success) {\n return { success: false, message: `Invalid arguments for '${command}': ${validation.error.issues[0].message}`, timestamp: new Date() };\n }\n\n return def.execute(args);\n }\n\n #commandHelp(name: string): CommandResult {\n if (name === 'clear') return { success: true, message: CLEAR_USAGE, timestamp: new Date() };\n if (name === 'help') return { success: true, message: HELP_USAGE, timestamp: new Date() };\n const def = this.registry.get(name);\n if (!def) return { success: false, message: `Unknown command: ${name}`, timestamp: new Date() };\n return { success: true, message: def.usage, timestamp: new Date() };\n }\n}\n","import { Component, computed, inject } from '@angular/core';\nimport { AuthenticationService } from '../../services/authentication.service';\nimport { CommandService } from '../../services/command.service';\nimport { TerminalFocusService } from '../../services/terminal-focus.service';\n\n@Component({\n selector: 'shell-status-bar',\n templateUrl: './status-bar.html',\n styleUrl: './status-bar.css',\n})\nexport class StatusBar {\n readonly #authService = inject(AuthenticationService);\n readonly #focusService = inject(TerminalFocusService);\n readonly #commandService = inject(CommandService);\n\n readonly isAuthenticated = this.#authService.authenticated;\n readonly loginStatus = computed(() =>\n this.#authService.authenticating()\n ? 'Authenticating...'\n : this.#authService.authenticated()\n ? 'Logged in'\n : 'Not logged in',\n );\n\n logout(): void {\n this.#authService.logout();\n this.#commandService.echoCommand('logout');\n this.#focusService.requestFocus();\n }\n}\n","<div class=\"status-bar\">\n <div class=\"status-item\">\n <span class=\"status-label text-secondary-info\">Status:</span>\n @if (isAuthenticated()) {\n <a class=\"status-value text-interactive logout-link\" (click)=\"logout()\">Log Out</a>\n } @else {\n <span class=\"status-value text-loss\">{{ loginStatus() }}</span>\n }\n </div>\n @if (isAuthenticated()) {\n <ng-content />\n }\n</div>\n","import { Component, computed, inject } from '@angular/core';\nimport { RouterLink, RouterLinkActive } from '@angular/router';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport { TerminalFocusService } from '../../services/terminal-focus.service';\nimport { CommandService } from '../../services/command.service';\nimport { KeyboardShortcutService } from '../../services/keyboard-shortcut.service';\nimport { SHELL_MENU_ITEMS } from '../../tokens/shell-tokens';\nimport { MenuItem } from '../../types/menu.types';\n\nexport { MenuItem };\n\n@Component({\n selector: 'shell-side-menu',\n imports: [RouterLink, RouterLinkActive, MatIconModule, MatTooltipModule],\n templateUrl: './side-menu.html',\n styleUrl: './side-menu.css',\n})\nexport class SideMenu {\n readonly #focusService = inject(TerminalFocusService);\n readonly #commandService = inject(CommandService);\n readonly #shortcutService = inject(KeyboardShortcutService);\n readonly hasShortcuts = this.#shortcutService.activeShortcuts;\n\n readonly #allMenuItems: MenuItem[] = inject(SHELL_MENU_ITEMS, { optional: true }) ?? [];\n\n readonly menuItems = computed(() =>\n this.#allMenuItems.filter(item => !item.visible || item.visible()),\n );\n\n onMenuClick(item: MenuItem): void {\n if (item.command) {\n this.#commandService.echoCommand(item.command);\n }\n this.#focusService.requestFocus();\n }\n\n toggleHelp(): void {\n this.#shortcutService.toggleHelp();\n }\n}\n","<nav class=\"side-menu\">\n @for (item of menuItems(); track item.route) {\n <a\n class=\"menu-item\"\n [routerLink]=\"item.route\"\n routerLinkActive=\"active\"\n [matTooltip]=\"item.label\"\n matTooltipPosition=\"right\"\n (click)=\"onMenuClick(item)\"\n >\n <mat-icon>{{ item.icon }}</mat-icon>\n </a>\n }\n <div class=\"menu-spacer\"></div>\n @if (hasShortcuts()) {\n <button\n class=\"help-button\"\n matTooltip=\"Keyboard shortcuts\"\n matTooltipPosition=\"right\"\n (click)=\"toggleHelp()\"\n >\n <span class=\"help-modifier\">Alt+</span><span class=\"help-key\">?</span>\n </button>\n }\n</nav>\n","import { Component, inject } from '@angular/core';\nimport { RouterOutlet } from '@angular/router';\nimport { MatProgressSpinnerModule } from '@angular/material/progress-spinner';\nimport { ThinkingService } from '../../services/thinking.service';\nimport { KeyboardShortcutService } from '../../services/keyboard-shortcut.service';\n\n@Component({\n selector: 'shell-main-content',\n imports: [RouterOutlet, MatProgressSpinnerModule],\n templateUrl: './main-content.html',\n styleUrl: './main-content.css',\n})\nexport class MainContent {\n readonly #thinkingService = inject(ThinkingService);\n readonly #shortcutService = inject(KeyboardShortcutService);\n readonly isThinking = this.#thinkingService.isThinking;\n readonly shortcutHelpVisible = this.#shortcutService.helpVisible;\n readonly activeShortcuts = this.#shortcutService.activeShortcuts;\n\n formatKey(key: string): string {\n const keyMap: Record<string, string> = {\n ArrowUp: '↑', ArrowDown: '↓', ArrowLeft: '←', ArrowRight: '→',\n PageUp: 'PgUp', PageDown: 'PgDn',\n };\n return keyMap[key] ?? key;\n }\n\n closeShortcutHelp(): void {\n this.#shortcutService.helpVisible.set(false);\n }\n}\n","<div class=\"main-content\">\n <div class=\"content-area\">\n <router-outlet />\n </div>\n @if (shortcutHelpVisible() && activeShortcuts()) {\n <div class=\"shortcut-overlay\" (click)=\"closeShortcutHelp()\">\n <div class=\"shortcut-panel\" (click)=\"$event.stopPropagation()\">\n <div class=\"shortcut-title text-secondary-info\">{{ activeShortcuts()!.groupId }} shortcuts</div>\n @for (s of activeShortcuts()!.shortcuts; track s.key) {\n <div class=\"shortcut-row\">\n <kbd class=\"shortcut-key\">Alt+{{ formatKey(s.key) }}</kbd>\n <span class=\"shortcut-desc text-text-primary\">{{ s.description }}</span>\n </div>\n }\n <div class=\"shortcut-row shortcut-dismiss\">\n <kbd class=\"shortcut-key\">Alt+?</kbd>\n <span class=\"shortcut-desc text-secondary-info\">or</span>\n <kbd class=\"shortcut-key\">Esc</kbd>\n <span class=\"shortcut-desc text-secondary-info\">dismiss</span>\n </div>\n </div>\n </div>\n }\n @if (isThinking()) {\n <div class=\"thinking-overlay\">\n <mat-spinner diameter=\"48\" />\n </div>\n }\n</div>\n","import { Component, inject, ElementRef, viewChild, effect, afterNextRender, computed } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { CommandService } from '../../services/command.service';\nimport { CommandRegistryService } from '../../services/command-registry.service';\nimport { AuthenticationService } from '../../services/authentication.service';\nimport { TerminalFocusService } from '../../services/terminal-focus.service';\nimport { CommandResult } from '../../types/command.types';\n\n@Component({\n selector: 'shell-command-terminal',\n imports: [FormsModule],\n templateUrl: './command-terminal.html',\n styleUrl: './command-terminal.css',\n})\nexport class CommandTerminal {\n private readonly commandService = inject(CommandService);\n private readonly registry = inject(CommandRegistryService);\n private readonly authService = inject(AuthenticationService);\n private readonly terminalFocusService = inject(TerminalFocusService);\n\n readonly history = computed(() => [...this.commandService.history()].reverse());\n readonly currentInput = this.commandService.currentInput;\n readonly isProcessing = this.commandService.isProcessing;\n\n private readonly inputEl = viewChild<ElementRef<HTMLInputElement>>('terminalInput');\n\n private tabCycleIndex = -1;\n private lastTabPrefix = '';\n\n readonly ghostText = computed(() => {\n const input = this.currentInput().trim();\n if (!input || input.includes(' ')) return '';\n const prefix = input.toLowerCase();\n const suggestions = this.registry.getSuggestions(prefix, this.authService.authenticated());\n return suggestions.length > 0 ? suggestions[0] : '';\n });\n\n constructor() {\n afterNextRender(() => this.focusInput());\n\n effect(() => {\n if (!this.isProcessing()) {\n setTimeout(() => this.focusInput());\n }\n });\n\n effect(() => {\n this.terminalFocusService.focusRequested();\n setTimeout(() => this.focusInput());\n });\n }\n\n onSubmit(): void {\n const input = this.currentInput();\n if (!input.trim()) return;\n this.commandService.execute(input);\n this.tabCycleIndex = -1;\n this.lastTabPrefix = '';\n this.focusInput();\n }\n\n onInputChange(value: string): void {\n this.currentInput.set(value);\n this.tabCycleIndex = -1;\n this.lastTabPrefix = '';\n }\n\n onTab(event: KeyboardEvent): void {\n event.preventDefault();\n const input = this.currentInput().trim();\n if (!input || input.includes(' ')) return;\n\n const prefix = input.toLowerCase();\n const suggestions = this.registry.getSuggestions(prefix, this.authService.authenticated());\n if (suggestions.length === 0) return;\n\n if (suggestions.length === 1) {\n this.currentInput.set(suggestions[0] + ' ');\n this.tabCycleIndex = -1;\n this.lastTabPrefix = '';\n return;\n }\n\n if (this.lastTabPrefix !== prefix) {\n this.lastTabPrefix = prefix;\n this.tabCycleIndex = -1;\n }\n\n if (event.shiftKey) {\n this.tabCycleIndex = this.tabCycleIndex <= 0 ? suggestions.length - 1 : this.tabCycleIndex - 1;\n } else {\n this.tabCycleIndex = (this.tabCycleIndex + 1) % suggestions.length;\n }\n\n this.currentInput.set(suggestions[this.tabCycleIndex]);\n }\n\n getSeverityClass(result: CommandResult): string {\n if (result.severity === 'info') return 'info';\n if (result.severity === 'warning') return 'warning';\n if (result.severity === 'error' || !result.success) return 'error';\n return '';\n }\n\n focusInput(): void {\n this.inputEl()?.nativeElement.focus();\n }\n}\n","<div class=\"terminal\">\n <div class=\"terminal-input-row\">\n <span class=\"prompt\">$</span>\n <div class=\"input-wrapper\">\n @if (ghostText()) {\n <input\n class=\"ghost-input\"\n type=\"text\"\n [value]=\"ghostText()\"\n disabled\n tabindex=\"-1\"\n aria-hidden=\"true\"\n />\n }\n <input\n #terminalInput\n class=\"terminal-input\"\n type=\"text\"\n [ngModel]=\"currentInput()\"\n (ngModelChange)=\"onInputChange($event)\"\n (keydown.enter)=\"onSubmit()\"\n (keydown.tab)=\"onTab($any($event))\"\n placeholder=\"Type a command...\"\n [disabled]=\"isProcessing()\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n />\n </div>\n </div>\n <div class=\"terminal-output\">\n @for (entry of history(); track entry.result.timestamp) {\n @if (entry.input) {\n <div class=\"terminal-line\">\n <span class=\"prompt\">$</span>\n <span class=\"command-text\">{{ entry.input }}@if ((entry.repeatCount ?? 1) > 1) { <span class=\"repeat-count\">(×{{ entry.repeatCount }})</span>}</span>\n </div>\n }\n @if (entry.result.message) {\n <div class=\"terminal-line\" [class]=\"getSeverityClass(entry.result)\">{{ entry.result.message }}</div>\n }\n }\n </div>\n</div>\n","import { Component, inject, signal } from '@angular/core';\nimport { StatusBar } from '../status-bar/status-bar';\nimport { SideMenu } from '../side-menu/side-menu';\nimport { MainContent } from '../main-content/main-content';\nimport { CommandTerminal } from '../command-terminal/command-terminal';\nimport { ThinkingService } from '../../services/thinking.service';\n\nconst MIN_TERMINAL_HEIGHT = 80;\nconst MAX_TERMINAL_RATIO = 0.6;\nconst DEFAULT_TERMINAL_HEIGHT = 160;\n\n@Component({\n selector: 'shell-root',\n imports: [StatusBar, SideMenu, MainContent, CommandTerminal],\n templateUrl: './shell.html',\n styleUrl: './shell.css',\n})\nexport class Shell {\n readonly #thinkingService = inject(ThinkingService);\n readonly isThinking = this.#thinkingService.isThinking;\n readonly terminalHeight = signal(`${DEFAULT_TERMINAL_HEIGHT}px`);\n readonly isDragging = signal(false);\n\n #startY = 0;\n #startHeight = DEFAULT_TERMINAL_HEIGHT;\n\n readonly #onMouseMove = (event: MouseEvent) => {\n const deltaY = event.clientY - this.#startY;\n const maxHeight = Math.floor(window.innerHeight * MAX_TERMINAL_RATIO);\n const newHeight = Math.min(maxHeight, Math.max(MIN_TERMINAL_HEIGHT, this.#startHeight - deltaY));\n this.terminalHeight.set(`${newHeight}px`);\n };\n\n readonly #onMouseUp = () => {\n this.isDragging.set(false);\n document.removeEventListener('mousemove', this.#onMouseMove);\n document.removeEventListener('mouseup', this.#onMouseUp);\n };\n\n onResizeStart(event: MouseEvent): void {\n event.preventDefault();\n this.#startY = event.clientY;\n this.#startHeight = parseInt(this.terminalHeight(), 10);\n this.isDragging.set(true);\n document.addEventListener('mousemove', this.#onMouseMove);\n document.addEventListener('mouseup', this.#onMouseUp);\n }\n}\n","<div class=\"shell\" [style.--terminal-height]=\"terminalHeight()\" [class.is-dragging]=\"isDragging()\">\n <shell-status-bar class=\"shell-status\" [class.disabled-zone]=\"isThinking()\">\n <ng-content />\n </shell-status-bar>\n <shell-side-menu class=\"shell-menu\" [class.disabled-zone]=\"isThinking()\" />\n <shell-main-content class=\"shell-main\" />\n <div class=\"shell-resize\" [class.dragging]=\"isDragging()\" (mousedown)=\"onResizeStart($event)\"></div>\n <shell-command-terminal class=\"shell-terminal\" [class.disabled-zone]=\"isThinking()\" />\n</div>\n","import { Component, inject, signal } from '@angular/core';\nimport { AutofillEvent, TextFieldModule } from '@angular/cdk/text-field';\nimport { Credentials, validateCredentials } from '@franzzemen/identity';\nimport { PASSWORD_REGEX, USERNAME_REGEX } from '@franzzemen/utility';\nimport { MatFormField, MatLabel } from '@angular/material/form-field';\nimport { MatInput, MatInputModule } from '@angular/material/input';\nimport { FormsModule } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatIconModule } from '@angular/material/icon';\nimport { Router } from '@angular/router';\nimport { DatePipe } from '@angular/common';\nimport { AuthenticationService } from '../../services/authentication.service';\nimport { CommandService } from '../../services/command.service';\nimport { TerminalFocusService } from '../../services/terminal-focus.service';\nimport { RegexValidatorDirective } from '../../directives/regex-validator.directive';\nimport { SHELL_APP_NAME } from '../../tokens/shell-tokens';\n\n@Component({\n selector: 'shell-login',\n templateUrl: './login.html',\n styleUrl: './login.css',\n imports: [\n FormsModule,\n MatFormField,\n MatLabel,\n MatInput,\n MatInputModule,\n MatButtonModule,\n MatIconModule,\n RegexValidatorDirective,\n TextFieldModule,\n DatePipe,\n ],\n})\nexport class Login {\n model: Credentials = { username: '', password: '' };\n submitted = false;\n hide = signal(true);\n errors: { ndx: number; message: string }[] = [];\n\n protected readonly USERNAME_REGEX = USERNAME_REGEX;\n protected readonly PASSWORD_REGEX = PASSWORD_REGEX;\n protected readonly appName = inject(SHELL_APP_NAME, { optional: true }) ?? 'Application';\n\n readonly #commandService = inject(CommandService);\n readonly #terminalFocusService = inject(TerminalFocusService);\n\n constructor(\n protected authenticationService: AuthenticationService,\n protected router: Router,\n ) {}\n\n onAutofill(event: AutofillEvent, inputEl: HTMLInputElement): void {\n if (event.isAutofilled) {\n setTimeout(() => {\n const length = inputEl.value.length;\n inputEl.setSelectionRange(length, length);\n });\n }\n }\n\n clickEvent(event: MouseEvent): void {\n this.hide.set(!this.hide());\n event.stopPropagation();\n }\n\n onSubmit(event: Event): void {\n this.errors = [];\n event.preventDefault();\n this.submitted = true;\n const result = validateCredentials(this.model);\n if (result === true) {\n this.#doLogin(false);\n } else {\n for (let ndx = 0; ndx < result.length; ndx++) {\n this.errors.push({\n ndx,\n message: `${result[ndx].message ?? 'Unknown error'}: ${result[ndx].field ?? 'Unknown field'} ${result[ndx].type ?? 'Unknown type'} Expected: ${result[ndx].expected} Actual: ${result[ndx].actual}`,\n });\n }\n this.submitted = false;\n }\n }\n\n onTakeOver(): void {\n this.errors = [];\n this.submitted = true;\n this.#doLogin(true);\n }\n\n onCancelConflict(): void {\n this.authenticationService.conflictSessions.set(undefined);\n this.submitted = false;\n }\n\n #doLogin(force: boolean): void {\n this.authenticationService\n .login(this.model, force)\n .then(() => {\n this.#commandService.echoCommand(`login ${this.model.username}`);\n this.router.navigate(['/']).then(() => {\n setTimeout(() => this.#terminalFocusService.requestFocus());\n }).catch(console.error);\n })\n .catch((err) => {\n if (err !== 'conflict') {\n this.errors.push({ ndx: 0, message: typeof err === 'string' ? err : 'Unable to login' });\n }\n this.submitted = false;\n });\n }\n}\n","@let usernameRegex = USERNAME_REGEX;\n@let passwordRegex = PASSWORD_REGEX;\n<div class=\"login-container\">\n <div class=\"login-header\">\n <h2 class=\"text-text-primary\">{{ appName }}</h2>\n <p class=\"text-secondary-info\">Sign in to continue</p>\n </div>\n <form #loginForm=\"ngForm\" (ngSubmit)=\"onSubmit($event)\" class=\"login-form\">\n <mat-form-field appearance=\"outline\" class=\"login-field\">\n <mat-label>Username</mat-label>\n <input\n #usernameInput\n matInput\n placeholder=\"Enter username\"\n [(ngModel)]=\"model.username\"\n name=\"username\"\n [disabled]=\"submitted\"\n required\n regexValidator\n [regex]=\"usernameRegex\"\n (cdkAutofill)=\"onAutofill($event, usernameInput)\"\n />\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"login-field\">\n <mat-label>Password</mat-label>\n <input\n #passwordInput\n matInput\n placeholder=\"Enter password\"\n [type]=\"hide() ? 'password' : 'text'\"\n [(ngModel)]=\"model.password\"\n name=\"password\"\n [disabled]=\"submitted\"\n regexValidator\n [regex]=\"passwordRegex\"\n (cdkAutofill)=\"onAutofill($event, passwordInput)\"\n />\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n (click)=\"clickEvent($event)\"\n [attr.aria-label]=\"'Hide password'\"\n [attr.aria-pressed]=\"hide()\"\n >\n <mat-icon>{{ hide() ? 'visibility_off' : 'visibility' }}</mat-icon>\n </button>\n </mat-form-field>\n <button mat-flat-button type=\"submit\" [disabled]=\"submitted\" class=\"login-button\">\n Login\n </button>\n </form>\n @if (errors.length > 0) {\n <div class=\"login-errors\">\n @for (error of errors; track error.ndx) {\n <div class=\"login-error text-loss\">{{ error.message }}</div>\n }\n </div>\n }\n @if (authenticationService.conflictSessions(); as sessions) {\n <div class=\"login-conflict\">\n @for (session of sessions; track $index) {\n <p class=\"text-secondary-info\">\n Already logged in from <strong>{{ session.appContext }}</strong>\n since {{ session.startEpoch | date:'short' }}.\n </p>\n }\n <p class=\"text-secondary-info\">Log in here and end that session?</p>\n <div class=\"login-conflict-actions\">\n <button mat-stroked-button type=\"button\" (click)=\"onCancelConflict()\">Cancel</button>\n <button mat-flat-button type=\"button\" (click)=\"onTakeOver()\">Take Over</button>\n </div>\n </div>\n }\n</div>\n","import { Component, inject } from '@angular/core';\nimport { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';\nimport { MatButtonModule } from '@angular/material/button';\n\nexport interface ConfirmDialogData {\n title: string;\n message: string;\n warningMessage?: string;\n confirmLabel?: string;\n cancelLabel?: string;\n}\n\n@Component({\n selector: 'shell-confirm-dialog',\n imports: [MatDialogModule, MatButtonModule],\n template: `\n <h2 mat-dialog-title>{{ data.title }}</h2>\n <mat-dialog-content>\n <p>{{ data.message }}</p>\n @if (data.warningMessage) {\n <p class=\"warning-message\">{{ data.warningMessage }}</p>\n }\n </mat-dialog-content>\n <mat-dialog-actions align=\"end\">\n <button mat-button (click)=\"dialogRef.close(false)\">{{ data.cancelLabel ?? 'Cancel' }}</button>\n <button mat-flat-button color=\"warn\" (click)=\"dialogRef.close(true)\">{{ data.confirmLabel ?? 'Confirm' }}</button>\n </mat-dialog-actions>\n `,\n styles: [`\n :host { display: block; }\n .warning-message { color: var(--color-warning); margin-top: 8px; }\n `],\n})\nexport class ConfirmDialog {\n readonly data = inject<ConfirmDialogData>(MAT_DIALOG_DATA);\n readonly dialogRef = inject(MatDialogRef<ConfirmDialog>);\n}\n","/*\n * Public API surface for @franzzemen/brokenstock-shell\n */\n\n// Types\nexport * from './lib/types/command.types';\nexport * from './lib/types/menu.types';\n\n// Tokens & config\nexport * from './lib/tokens/shell-tokens';\nexport * from './lib/provide-shell-config';\n\n// Guards\nexport * from './lib/guards/auth.guard';\n\n// Interceptors\nexport * from './lib/interceptors/auth.interceptor';\n\n// Directives\nexport * from './lib/directives/regex-validator.directive';\n\n// Services\nexport * from './lib/services/thinking.service';\nexport * from './lib/services/theme.service';\nexport * from './lib/services/terminal-focus.service';\nexport * from './lib/services/keyboard-shortcut.service';\nexport * from './lib/services/authentication.service';\nexport * from './lib/services/command-registry.service';\nexport * from './lib/services/command.service';\n\n// Commands\nexport * from './lib/commands/command.utils';\n\n// Components\nexport * from './lib/components/shell/shell';\nexport * from './lib/components/side-menu/side-menu';\nexport * from './lib/components/status-bar/status-bar';\nexport * from './lib/components/main-content/main-content';\nexport * from './lib/components/command-terminal/command-terminal';\nexport * from './lib/components/login/login';\nexport * from './lib/components/confirm-dialog/confirm-dialog';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1","i1.AuthenticationService","i2"],"mappings":"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"}
1
+ {"version":3,"file":"franzzemen-brokenstock-shell.mjs","sources":["../../src/lib/tokens/shell-tokens.ts","../../src/lib/provide-shell-config.ts","../../src/lib/services/thinking.service.ts","../../src/lib/services/authentication.service.ts","../../src/lib/guards/auth.guard.ts","../../src/lib/interceptors/auth.interceptor.ts","../../src/lib/directives/regex-validator.directive.ts","../../src/lib/services/theme.service.ts","../../src/lib/services/terminal-focus.service.ts","../../src/lib/services/keyboard-shortcut.service.ts","../../src/lib/services/command-registry.service.ts","../../src/lib/commands/command.utils.ts","../../src/lib/services/command.service.ts","../../src/lib/components/status-bar/status-bar.ts","../../src/lib/components/status-bar/status-bar.html","../../src/lib/components/side-menu/side-menu.ts","../../src/lib/components/side-menu/side-menu.html","../../src/lib/components/main-content/main-content.ts","../../src/lib/components/main-content/main-content.html","../../src/lib/components/command-terminal/command-terminal.ts","../../src/lib/components/command-terminal/command-terminal.html","../../src/lib/components/shell/shell.ts","../../src/lib/components/shell/shell.html","../../src/lib/components/login/login.ts","../../src/lib/components/login/login.html","../../src/lib/components/confirm-dialog/confirm-dialog.ts","../../src/public-api.ts","../../src/franzzemen-brokenstock-shell.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\nimport { CommandDefinition } from '../types/command.types';\nimport { MenuItem } from '../types/menu.types';\n\nexport interface ShellAuthUrls {\n login: string;\n logout: string;\n refresh: string;\n}\n\nexport const SHELL_APP_NAME = new InjectionToken<string>('SHELL_APP_NAME');\nexport const SHELL_MENU_ITEMS = new InjectionToken<MenuItem[]>('SHELL_MENU_ITEMS');\nexport const SHELL_AUTH_URLS = new InjectionToken<ShellAuthUrls>('SHELL_AUTH_URLS');\n\n/**\n * App-specific commands to register alongside the built-in command set.\n * Provide via provideShellConfig().\n */\nexport const SHELL_COMMANDS = new InjectionToken<CommandDefinition[]>('SHELL_COMMANDS');\n","import { EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\nimport { CommandDefinition } from './types/command.types';\nimport { MenuItem } from './types/menu.types';\nimport { SHELL_APP_NAME, SHELL_AUTH_URLS, SHELL_COMMANDS, SHELL_MENU_ITEMS, ShellAuthUrls } from './tokens/shell-tokens';\n\nexport interface ShellConfig {\n appName: string;\n menuItems: MenuItem[];\n authUrls: ShellAuthUrls;\n commands?: CommandDefinition[];\n}\n\nexport function provideShellConfig(config: ShellConfig): EnvironmentProviders {\n return makeEnvironmentProviders([\n { provide: SHELL_APP_NAME, useValue: config.appName },\n { provide: SHELL_MENU_ITEMS, useValue: config.menuItems },\n { provide: SHELL_AUTH_URLS, useValue: config.authUrls },\n { provide: SHELL_COMMANDS, useValue: config.commands ?? [] },\n ]);\n}\n","import { Injectable, signal, computed } from '@angular/core';\n\n@Injectable({ providedIn: 'root' })\nexport class ThinkingService {\n readonly #activeCount = signal(0);\n\n readonly isThinking = computed(() => this.#activeCount() > 0);\n\n startThinking(): void {\n this.#activeCount.update(c => c + 1);\n }\n\n stopThinking(): void {\n this.#activeCount.update(c => Math.max(0, c - 1));\n }\n\n reset(): void {\n this.#activeCount.set(0);\n }\n}\n","import { computed, inject, Injectable, signal } from '@angular/core';\nimport { BEARER_TOKEN_REGEX, BearerToken, HttpHeader } from '@franzzemen/utility';\nimport { AuthenticationResponse, Credentials, EffectivePermissions, RoleNames, SessionSummary, UserSession, validateCredentials } from '@franzzemen/identity';\nimport { HttpClient, HttpErrorResponse, HttpResponse } from '@angular/common/http';\nimport { Router } from '@angular/router';\nimport { ThinkingService } from './thinking.service';\nimport { SHELL_AUTH_URLS } from '../tokens/shell-tokens';\n\n@Injectable({ providedIn: 'root' })\nexport class AuthenticationService {\n readonly authenticated = signal(false);\n readonly authenticating = signal(false);\n readonly userSession = signal<UserSession | undefined>(undefined);\n readonly effectivePermissions = signal<EffectivePermissions>({});\n readonly conflictSessions = signal<SessionSummary[] | undefined>(undefined);\n\n #refreshing: Promise<boolean> | null = null;\n #auth: BearerToken = 'Bearer ..' as BearerToken;\n\n readonly #httpClient = inject(HttpClient);\n readonly #thinkingService = inject(ThinkingService);\n readonly #router = inject(Router);\n readonly #authUrls = inject(SHELL_AUTH_URLS);\n\n get auth(): BearerToken {\n return this.#auth;\n }\n\n /** Check if the current user has a specific role. */\n hasRole(roleName: RoleNames): boolean {\n return this.authenticated() && this.userSession()?.roles.includes(roleName) === true;\n }\n\n /** Check if the current user has any of the specified roles. */\n hasAnyRole(roleNames: RoleNames[]): boolean {\n return this.authenticated() && roleNames.some(r => this.userSession()?.roles.includes(r) === true);\n }\n\n refresh(): Promise<boolean> {\n if (this.#refreshing) {\n return this.#refreshing;\n }\n this.#refreshing = this.#doRefresh().finally(() => { this.#refreshing = null; });\n return this.#refreshing;\n }\n\n logout(): void {\n const subscription = this.#httpClient\n .get<void>(this.#authUrls.logout, {\n headers: {\n [HttpHeader.Authorization]: this.#auth,\n [HttpHeader.AppContext]: 'brokenstock',\n },\n })\n .subscribe({\n next: () => {\n this.#clearSession();\n subscription.unsubscribe();\n },\n error: () => {\n this.#thinkingService.reset();\n this.#clearSession();\n },\n });\n }\n\n login(credentials: Credentials, force = false): Promise<void> {\n const validation = validateCredentials(credentials);\n if (validation !== true) {\n return Promise.reject('Invalid credentials');\n }\n this.conflictSessions.set(undefined);\n this.#thinkingService.startThinking();\n return new Promise((resolve, reject) => {\n this.authenticating.set(true);\n const body = force ? {...credentials, force: true} : credentials;\n const subscription = this.#httpClient\n .post<HttpResponse<AuthenticationResponse>>(\n this.#authUrls.login,\n body,\n {\n headers: {\n [HttpHeader.ContentType]: 'application/json',\n [HttpHeader.AppContext]: 'brokenstock',\n },\n observe: 'response',\n responseType: 'json',\n withCredentials: true,\n },\n )\n .subscribe({\n next: (response: HttpResponse<any>) => {\n try {\n const authResponse: AuthenticationResponse = response.body;\n // @ts-ignore\n delete authResponse.session.token;\n this.userSession.set(authResponse.session);\n this.effectivePermissions.set(authResponse.effectivePermissions ?? {});\n const auth = response.headers.get(HttpHeader.Authorization);\n if (!auth || !BEARER_TOKEN_REGEX.test(auth)) {\n reject('Unable to login');\n return;\n }\n this.#auth = auth as BearerToken;\n this.authenticated.set(true);\n resolve();\n } catch {\n reject('Unable to login');\n } finally {\n this.authenticating.set(false);\n subscription.unsubscribe();\n this.#thinkingService.stopThinking();\n }\n },\n error: (err: HttpErrorResponse) => {\n try {\n if (err.status === 409) {\n this.conflictSessions.set(err.error?.activeSessions ?? []);\n reject('conflict');\n } else {\n reject(err.message ?? 'Unable to login');\n }\n } finally {\n this.authenticating.set(false);\n subscription.unsubscribe();\n this.#thinkingService.stopThinking();\n }\n },\n });\n });\n }\n\n async #doRefresh(): Promise<boolean> {\n try {\n const response = await fetch(this.#authUrls.refresh, {\n method: 'POST',\n headers: {\n [HttpHeader.Authorization]: this.#auth,\n [HttpHeader.AppContext]: 'brokenstock',\n },\n credentials: 'include',\n });\n if (!response.ok) return false;\n const auth = response.headers.get(HttpHeader.Authorization);\n if (!auth || !BEARER_TOKEN_REGEX.test(auth)) return false;\n const body: AuthenticationResponse = await response.json();\n this.#auth = auth as BearerToken;\n this.userSession.set(body.session);\n this.effectivePermissions.set(body.effectivePermissions ?? {});\n return true;\n } catch {\n return false;\n }\n }\n\n #clearSession(): void {\n this.authenticated.set(false);\n this.userSession.set(undefined);\n this.effectivePermissions.set({});\n this.conflictSessions.set(undefined);\n this.#auth = 'Bearer ..' as BearerToken;\n this.#router.navigate(['/login']).catch(console.error);\n }\n}\n","import { inject } from '@angular/core';\nimport { CanActivateFn, Router } from '@angular/router';\nimport { AuthenticationService } from '../services/authentication.service';\n\nexport const authGuard: CanActivateFn = () => {\n const authService = inject(AuthenticationService);\n const router = inject(Router);\n\n if (authService.authenticated()) {\n return true;\n }\n return router.createUrlTree(['/login']);\n};\n","import { HttpInterceptorFn } from '@angular/common/http';\nimport { inject } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { from, switchMap, catchError, tap, throwError } from 'rxjs';\nimport { AuthenticationService } from '../services/authentication.service';\nimport { ThinkingService } from '../services/thinking.service';\nimport { SHELL_AUTH_URLS } from '../tokens/shell-tokens';\nimport { HttpHeader } from '@franzzemen/utility';\n\nexport const authInterceptor: HttpInterceptorFn = (req, next) => {\n const authService = inject(AuthenticationService);\n const thinkingService = inject(ThinkingService);\n const authUrls = inject(SHELL_AUTH_URLS);\n const router = inject(Router);\n\n return next(req).pipe(\n tap({\n next: (event) => {\n if ('headers' in event && event.headers?.get('x-permissions-stale') === 'true') {\n authService.refresh();\n }\n },\n }),\n catchError((error) => {\n const isRefreshOrLogin = req.url === authUrls.refresh || req.url === authUrls.login;\n if (error.status === 401 && !isRefreshOrLogin) {\n return from(authService.refresh()).pipe(\n switchMap((refreshed) => {\n if (refreshed) {\n const retryReq = req.clone({\n setHeaders: { [HttpHeader.Authorization]: authService.auth },\n });\n return next(retryReq);\n }\n thinkingService.reset();\n authService.authenticated.set(false);\n authService.userSession.set(undefined);\n router.navigate(['/login']);\n return throwError(() => error);\n }),\n catchError(() => {\n thinkingService.reset();\n authService.authenticated.set(false);\n authService.userSession.set(undefined);\n router.navigate(['/login']);\n return throwError(() => error);\n }),\n );\n }\n return throwError(() => error);\n }),\n );\n};\n","import { Directive, input } from '@angular/core';\nimport { AbstractControl, NG_VALIDATORS, ValidationErrors, Validator } from '@angular/forms';\n\n@Directive({\n selector: '[regexValidator]',\n providers: [{ provide: NG_VALIDATORS, useExisting: RegexValidatorDirective, multi: true }],\n})\nexport class RegexValidatorDirective implements Validator {\n regex = input(/^[A-Z0-9._%+-@!?]{4,64}$/i);\n\n validate(control: AbstractControl): ValidationErrors | null {\n if (!control.value || !this.regex().test(control.value)) {\n return { regexValidator: { value: control.value } };\n }\n return null;\n }\n}\n","import { Injectable, signal, computed } from '@angular/core';\n\nexport type ThemeMode = 'dark';\n\n@Injectable({ providedIn: 'root' })\nexport class ThemeService {\n readonly mode = signal<ThemeMode>('dark');\n readonly isDark = computed(() => this.mode() === 'dark');\n}\n","import { Injectable, signal } from '@angular/core';\n\n@Injectable({ providedIn: 'root' })\nexport class TerminalFocusService {\n readonly focusRequested = signal(0);\n\n requestFocus(): void {\n this.focusRequested.update(v => v + 1);\n }\n}\n","import { computed, inject, Injectable, NgZone, signal } from '@angular/core';\nimport { DOCUMENT } from '@angular/common';\nimport { TerminalFocusService } from './terminal-focus.service';\n\nexport interface ShortcutRegistration {\n key: string;\n modifier?: 'Alt';\n action: () => void;\n description: string;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class KeyboardShortcutService {\n readonly #groups = new Map<string, ShortcutRegistration[]>();\n readonly #activeGroupId = signal<string | null>(null);\n\n readonly #document = inject(DOCUMENT);\n readonly #zone = inject(NgZone);\n readonly #focusService = inject(TerminalFocusService);\n\n readonly helpVisible = signal(false);\n\n readonly activeShortcuts = computed(() => {\n const groupId = this.#activeGroupId();\n if (!groupId) return null;\n const shortcuts = this.#groups.get(groupId);\n if (!shortcuts) return null;\n return { groupId, shortcuts };\n });\n\n constructor() {\n this.#zone.runOutsideAngular(() => {\n this.#document.addEventListener('keydown', (event: KeyboardEvent) => {\n this.#handleKeydown(event);\n });\n });\n }\n\n registerGroup(groupId: string, shortcuts: ShortcutRegistration[]): void {\n this.#groups.set(groupId, shortcuts);\n this.#activeGroupId.set(groupId);\n }\n\n unregisterGroup(groupId: string): void {\n this.#groups.delete(groupId);\n if (this.#activeGroupId() === groupId) {\n const keys = [...this.#groups.keys()];\n this.#activeGroupId.set(keys.length > 0 ? keys[keys.length - 1] : null);\n }\n }\n\n toggleHelp(): void {\n this.helpVisible.update(v => !v);\n }\n\n #handleKeydown(event: KeyboardEvent): boolean {\n const activeId = this.#activeGroupId();\n if (activeId) {\n const shortcuts = this.#groups.get(activeId);\n if (shortcuts) {\n const match = shortcuts.find(s => {\n if (s.modifier === 'Alt') return event.altKey && s.key === event.key;\n return !event.altKey && !event.ctrlKey && !event.metaKey && s.key === event.key;\n });\n if (match) {\n event.preventDefault();\n this.#zone.run(() => match.action());\n return true;\n }\n }\n }\n\n if (event.key === 'Escape') {\n event.preventDefault();\n this.#zone.run(() => {\n this.helpVisible.set(false);\n this.#focusService.requestFocus();\n });\n return true;\n }\n\n if (!event.altKey) return false;\n\n if (event.key === '?' || event.key === '/') {\n event.preventDefault();\n this.#zone.run(() => this.toggleHelp());\n return true;\n }\n\n return false;\n }\n}\n","import { inject, Injectable } from '@angular/core';\nimport { CommandDefinition } from '../types/command.types';\nimport { SHELL_COMMANDS } from '../tokens/shell-tokens';\n\n@Injectable({ providedIn: 'root' })\nexport class CommandRegistryService {\n private readonly commands = new Map<string, CommandDefinition>();\n\n constructor() {\n const appCommands = inject(SHELL_COMMANDS, { optional: true }) ?? [];\n for (const cmd of appCommands) {\n this.register(cmd);\n }\n }\n\n register(command: CommandDefinition): void {\n this.commands.set(command.name, command);\n }\n\n get(name: string): CommandDefinition | undefined {\n return this.commands.get(name);\n }\n\n getAll(): CommandDefinition[] {\n return Array.from(this.commands.values());\n }\n\n /**\n * Returns command name suggestions for tab-completion.\n * Built-ins (clear, help) are included when authenticated.\n */\n getSuggestions(prefix: string, isAuthenticated: boolean): string[] {\n if (!prefix) return [];\n if (!isAuthenticated) {\n return 'login'.startsWith(prefix) && 'login' !== prefix ? ['login'] : [];\n }\n const builtIns = ['clear', 'help'];\n const registered = [...this.commands.values()].map(c => c.name);\n return [...builtIns, ...registered]\n .filter(name => name.startsWith(prefix) && name !== prefix)\n .sort();\n }\n}\n","/**\n * Quote-aware command tokenizer. Treats \"...\" as single tokens and strips enclosing quotes.\n */\nexport function tokenize(input: string): string[] {\n return (input.match(/(?:\"[^\"]*\"|\\S)+/g) ?? []).map(t => t.replace(/\"([^\"]*)\"/g, '$1'));\n}\n\nexport const CLEAR_USAGE =\n 'clear\\n\\n' +\n ' Clears the terminal history.\\n' +\n ' No arguments required.';\n\nexport const HELP_USAGE =\n 'help [command]\\n\\n' +\n ' With no arguments, lists all available commands.\\n' +\n ' With a command name, shows detailed usage for that command.\\n\\n' +\n ' Arguments:\\n' +\n ' [command] Optional command name to show detailed help for';\n","import { inject, Injectable, signal, computed, effect } from '@angular/core';\nimport { z } from 'zod/v4';\nimport { CommandResult, CommandHistoryEntry, Severity } from '../types/command.types';\nimport { tokenize, CLEAR_USAGE, HELP_USAGE } from '../commands/command.utils';\nimport { CommandRegistryService } from './command-registry.service';\nimport { AuthenticationService } from './authentication.service';\n\nexport type { CommandResult, CommandHistoryEntry, Severity };\n\nconst CommandInputSchema = z.string().trim().min(1, 'Command cannot be empty');\n\n@Injectable({ providedIn: 'root' })\nexport class CommandService {\n readonly history = signal<CommandHistoryEntry[]>([]);\n readonly currentInput = signal('');\n readonly isProcessing = signal(false);\n\n private readonly authService = inject(AuthenticationService);\n private readonly registry = inject(CommandRegistryService);\n\n constructor() {\n effect(() => {\n if (!this.authService.authenticated()) {\n this.history.set([]);\n }\n });\n }\n\n readonly lastResult = computed(() => {\n const h = this.history();\n return h.length > 0 ? h[h.length - 1].result : null;\n });\n\n echoCommand(input: string): void {\n if (this.#coalesce(input)) return;\n this.history.update(h => [...h, {\n input,\n result: { success: true, message: '', timestamp: new Date() },\n repeatCount: 1,\n }]);\n }\n\n pushNotification(notification: { message: string; severity: Severity }): void {\n this.history.update(h => [...h, {\n input: '',\n result: {\n success: notification.severity !== 'error',\n message: notification.message,\n timestamp: new Date(),\n severity: notification.severity,\n },\n }]);\n }\n\n execute(rawInput: string): void {\n const validation = CommandInputSchema.safeParse(rawInput);\n if (!validation.success) {\n this.history.update(h => [...h, {\n input: rawInput,\n result: { success: false, message: validation.error.issues[0].message, timestamp: new Date() },\n }]);\n this.currentInput.set('');\n return;\n }\n\n const input = validation.data;\n const parts = tokenize(input);\n const command = parts[0].toLowerCase();\n\n const def = this.registry.get(command);\n const displayInput = def?.sanitizeInput ? def.sanitizeInput(input) : input;\n\n const resultOrPromise = this.#dispatch(command, parts.slice(1));\n this.currentInput.set('');\n\n if (resultOrPromise instanceof Promise) {\n this.isProcessing.set(true);\n resultOrPromise\n .then(result => {\n if (!this.#coalesce(displayInput)) {\n this.history.update(h => [...h, { input: displayInput, result, repeatCount: 1 }]);\n }\n })\n .finally(() => this.isProcessing.set(false));\n } else {\n if (!this.#coalesce(displayInput)) {\n this.history.update(h => [...h, { input: displayInput, result: resultOrPromise, repeatCount: 1 }]);\n }\n }\n }\n\n #coalesce(input: string): boolean {\n if (!input) return false;\n const h = this.history();\n for (let i = h.length - 1; i >= 0; i--) {\n if (h[i].input) {\n if (h[i].input === input) {\n this.history.update(history => {\n const updated = [...history];\n updated[i] = { ...updated[i], repeatCount: (updated[i].repeatCount ?? 1) + 1 };\n return updated;\n });\n return true;\n }\n return false;\n }\n }\n return false;\n }\n\n #dispatch(command: string, args: string[]): CommandResult | Promise<CommandResult> {\n const hasHelp = args.some(a => a.toLowerCase() === 'help');\n const isAuthenticated = this.authService.authenticated();\n\n if (!isAuthenticated && command !== 'login') {\n return { success: false, message: 'Not logged in. Use \"login\" to authenticate.', timestamp: new Date() };\n }\n\n if (command === 'clear') {\n if (hasHelp) return { success: true, message: CLEAR_USAGE, timestamp: new Date() };\n this.history.set([]);\n return { success: true, message: '', timestamp: new Date() };\n }\n\n if (command === 'help') {\n const target = args[0]?.toLowerCase();\n if (target) return this.#commandHelp(target);\n const registered = this.registry.getAll();\n const lines = [\n ' clear — Clear terminal history',\n ' help — List available commands',\n ...registered.map(c => ` ${c.name} — ${c.description}`),\n ];\n return {\n success: true,\n message: 'Available commands:\\n' + lines.join('\\n') + '\\n\\nType \"help <command>\" or \"<command> help\" for detailed usage.',\n timestamp: new Date(),\n };\n }\n\n const def = this.registry.get(command);\n if (!def) {\n return { success: false, message: `Unknown command: ${command}`, timestamp: new Date() };\n }\n\n if (hasHelp) {\n return { success: true, message: def.usage, timestamp: new Date() };\n }\n\n const validation = def.argsSchema.safeParse(args);\n if (!validation.success) {\n return { success: false, message: `Invalid arguments for '${command}': ${validation.error.issues[0].message}`, timestamp: new Date() };\n }\n\n return def.execute(args);\n }\n\n #commandHelp(name: string): CommandResult {\n if (name === 'clear') return { success: true, message: CLEAR_USAGE, timestamp: new Date() };\n if (name === 'help') return { success: true, message: HELP_USAGE, timestamp: new Date() };\n const def = this.registry.get(name);\n if (!def) return { success: false, message: `Unknown command: ${name}`, timestamp: new Date() };\n return { success: true, message: def.usage, timestamp: new Date() };\n }\n}\n","import { Component, computed, inject } from '@angular/core';\nimport { AuthenticationService } from '../../services/authentication.service';\nimport { CommandService } from '../../services/command.service';\nimport { TerminalFocusService } from '../../services/terminal-focus.service';\n\n@Component({\n selector: 'shell-status-bar',\n templateUrl: './status-bar.html',\n styleUrl: './status-bar.css',\n})\nexport class StatusBar {\n readonly #authService = inject(AuthenticationService);\n readonly #focusService = inject(TerminalFocusService);\n readonly #commandService = inject(CommandService);\n\n readonly isAuthenticated = this.#authService.authenticated;\n readonly loginStatus = computed(() =>\n this.#authService.authenticating()\n ? 'Authenticating...'\n : this.#authService.authenticated()\n ? 'Logged in'\n : 'Not logged in',\n );\n\n logout(): void {\n this.#authService.logout();\n this.#commandService.echoCommand('logout');\n this.#focusService.requestFocus();\n }\n}\n","<div class=\"status-bar\">\n <div class=\"status-item\">\n <span class=\"status-label text-secondary-info\">Status:</span>\n @if (isAuthenticated()) {\n <a class=\"status-value text-interactive logout-link\" (click)=\"logout()\">Log Out</a>\n } @else {\n <span class=\"status-value text-loss\">{{ loginStatus() }}</span>\n }\n </div>\n @if (isAuthenticated()) {\n <ng-content />\n }\n</div>\n","import { Component, computed, inject } from '@angular/core';\nimport { RouterLink, RouterLinkActive } from '@angular/router';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport { TerminalFocusService } from '../../services/terminal-focus.service';\nimport { CommandService } from '../../services/command.service';\nimport { KeyboardShortcutService } from '../../services/keyboard-shortcut.service';\nimport { SHELL_MENU_ITEMS } from '../../tokens/shell-tokens';\nimport { MenuItem } from '../../types/menu.types';\n\nexport { MenuItem };\n\n@Component({\n selector: 'shell-side-menu',\n imports: [RouterLink, RouterLinkActive, MatIconModule, MatTooltipModule],\n templateUrl: './side-menu.html',\n styleUrl: './side-menu.css',\n})\nexport class SideMenu {\n readonly #focusService = inject(TerminalFocusService);\n readonly #commandService = inject(CommandService);\n readonly #shortcutService = inject(KeyboardShortcutService);\n readonly hasShortcuts = this.#shortcutService.activeShortcuts;\n\n readonly #allMenuItems: MenuItem[] = inject(SHELL_MENU_ITEMS, { optional: true }) ?? [];\n\n readonly menuItems = computed(() =>\n this.#allMenuItems.filter(item => !item.visible || item.visible()),\n );\n\n onMenuClick(item: MenuItem): void {\n if (item.command) {\n this.#commandService.echoCommand(item.command);\n }\n this.#focusService.requestFocus();\n }\n\n toggleHelp(): void {\n this.#shortcutService.toggleHelp();\n }\n}\n","<nav class=\"side-menu\">\n @for (item of menuItems(); track item.route) {\n <a\n class=\"menu-item\"\n [routerLink]=\"item.route\"\n routerLinkActive=\"active\"\n [matTooltip]=\"item.label\"\n matTooltipPosition=\"right\"\n (click)=\"onMenuClick(item)\"\n >\n <mat-icon>{{ item.icon }}</mat-icon>\n </a>\n }\n <div class=\"menu-spacer\"></div>\n @if (hasShortcuts()) {\n <button\n class=\"help-button\"\n matTooltip=\"Keyboard shortcuts\"\n matTooltipPosition=\"right\"\n (click)=\"toggleHelp()\"\n >\n <span class=\"help-modifier\">Alt+</span><span class=\"help-key\">?</span>\n </button>\n }\n</nav>\n","import { Component, inject } from '@angular/core';\nimport { RouterOutlet } from '@angular/router';\nimport { MatProgressSpinnerModule } from '@angular/material/progress-spinner';\nimport { ThinkingService } from '../../services/thinking.service';\nimport { KeyboardShortcutService } from '../../services/keyboard-shortcut.service';\n\n@Component({\n selector: 'shell-main-content',\n imports: [RouterOutlet, MatProgressSpinnerModule],\n templateUrl: './main-content.html',\n styleUrl: './main-content.css',\n})\nexport class MainContent {\n readonly #thinkingService = inject(ThinkingService);\n readonly #shortcutService = inject(KeyboardShortcutService);\n readonly isThinking = this.#thinkingService.isThinking;\n readonly shortcutHelpVisible = this.#shortcutService.helpVisible;\n readonly activeShortcuts = this.#shortcutService.activeShortcuts;\n\n formatKey(key: string): string {\n const keyMap: Record<string, string> = {\n ArrowUp: '↑', ArrowDown: '↓', ArrowLeft: '←', ArrowRight: '→',\n PageUp: 'PgUp', PageDown: 'PgDn',\n };\n return keyMap[key] ?? key;\n }\n\n closeShortcutHelp(): void {\n this.#shortcutService.helpVisible.set(false);\n }\n}\n","<div class=\"main-content\">\n <div class=\"content-area\">\n <router-outlet />\n </div>\n @if (shortcutHelpVisible() && activeShortcuts()) {\n <div class=\"shortcut-overlay\" (click)=\"closeShortcutHelp()\">\n <div class=\"shortcut-panel\" (click)=\"$event.stopPropagation()\">\n <div class=\"shortcut-title text-secondary-info\">{{ activeShortcuts()!.groupId }} shortcuts</div>\n @for (s of activeShortcuts()!.shortcuts; track s.key) {\n <div class=\"shortcut-row\">\n <kbd class=\"shortcut-key\">Alt+{{ formatKey(s.key) }}</kbd>\n <span class=\"shortcut-desc text-text-primary\">{{ s.description }}</span>\n </div>\n }\n <div class=\"shortcut-row shortcut-dismiss\">\n <kbd class=\"shortcut-key\">Alt+?</kbd>\n <span class=\"shortcut-desc text-secondary-info\">or</span>\n <kbd class=\"shortcut-key\">Esc</kbd>\n <span class=\"shortcut-desc text-secondary-info\">dismiss</span>\n </div>\n </div>\n </div>\n }\n @if (isThinking()) {\n <div class=\"thinking-overlay\">\n <mat-spinner diameter=\"48\" />\n </div>\n }\n</div>\n","import { Component, inject, ElementRef, viewChild, effect, afterNextRender, computed } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { CommandService } from '../../services/command.service';\nimport { CommandRegistryService } from '../../services/command-registry.service';\nimport { AuthenticationService } from '../../services/authentication.service';\nimport { TerminalFocusService } from '../../services/terminal-focus.service';\nimport { CommandResult } from '../../types/command.types';\n\n@Component({\n selector: 'shell-command-terminal',\n imports: [FormsModule],\n templateUrl: './command-terminal.html',\n styleUrl: './command-terminal.css',\n})\nexport class CommandTerminal {\n private readonly commandService = inject(CommandService);\n private readonly registry = inject(CommandRegistryService);\n private readonly authService = inject(AuthenticationService);\n private readonly terminalFocusService = inject(TerminalFocusService);\n\n readonly history = computed(() => [...this.commandService.history()].reverse());\n readonly currentInput = this.commandService.currentInput;\n readonly isProcessing = this.commandService.isProcessing;\n\n private readonly inputEl = viewChild<ElementRef<HTMLInputElement>>('terminalInput');\n\n private tabCycleIndex = -1;\n private lastTabPrefix = '';\n\n readonly ghostText = computed(() => {\n const input = this.currentInput().trim();\n if (!input || input.includes(' ')) return '';\n const prefix = input.toLowerCase();\n const suggestions = this.registry.getSuggestions(prefix, this.authService.authenticated());\n return suggestions.length > 0 ? suggestions[0] : '';\n });\n\n constructor() {\n afterNextRender(() => this.focusInput());\n\n effect(() => {\n if (!this.isProcessing()) {\n setTimeout(() => this.focusInput());\n }\n });\n\n effect(() => {\n this.terminalFocusService.focusRequested();\n setTimeout(() => this.focusInput());\n });\n }\n\n onSubmit(): void {\n const input = this.currentInput();\n if (!input.trim()) return;\n this.commandService.execute(input);\n this.tabCycleIndex = -1;\n this.lastTabPrefix = '';\n this.focusInput();\n }\n\n onInputChange(value: string): void {\n this.currentInput.set(value);\n this.tabCycleIndex = -1;\n this.lastTabPrefix = '';\n }\n\n onTab(event: KeyboardEvent): void {\n event.preventDefault();\n const input = this.currentInput().trim();\n if (!input || input.includes(' ')) return;\n\n const prefix = input.toLowerCase();\n const suggestions = this.registry.getSuggestions(prefix, this.authService.authenticated());\n if (suggestions.length === 0) return;\n\n if (suggestions.length === 1) {\n this.currentInput.set(suggestions[0] + ' ');\n this.tabCycleIndex = -1;\n this.lastTabPrefix = '';\n return;\n }\n\n if (this.lastTabPrefix !== prefix) {\n this.lastTabPrefix = prefix;\n this.tabCycleIndex = -1;\n }\n\n if (event.shiftKey) {\n this.tabCycleIndex = this.tabCycleIndex <= 0 ? suggestions.length - 1 : this.tabCycleIndex - 1;\n } else {\n this.tabCycleIndex = (this.tabCycleIndex + 1) % suggestions.length;\n }\n\n this.currentInput.set(suggestions[this.tabCycleIndex]);\n }\n\n getSeverityClass(result: CommandResult): string {\n if (result.severity === 'info') return 'info';\n if (result.severity === 'warning') return 'warning';\n if (result.severity === 'error' || !result.success) return 'error';\n return '';\n }\n\n focusInput(): void {\n this.inputEl()?.nativeElement.focus();\n }\n}\n","<div class=\"terminal\">\n <div class=\"terminal-input-row\">\n <span class=\"prompt\">$</span>\n <div class=\"input-wrapper\">\n @if (ghostText()) {\n <input\n class=\"ghost-input\"\n type=\"text\"\n [value]=\"ghostText()\"\n disabled\n tabindex=\"-1\"\n aria-hidden=\"true\"\n />\n }\n <input\n #terminalInput\n class=\"terminal-input\"\n type=\"text\"\n [ngModel]=\"currentInput()\"\n (ngModelChange)=\"onInputChange($event)\"\n (keydown.enter)=\"onSubmit()\"\n (keydown.tab)=\"onTab($any($event))\"\n placeholder=\"Type a command...\"\n [disabled]=\"isProcessing()\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n />\n </div>\n </div>\n <div class=\"terminal-output\">\n @for (entry of history(); track entry.result.timestamp) {\n @if (entry.input) {\n <div class=\"terminal-line\">\n <span class=\"prompt\">$</span>\n <span class=\"command-text\">{{ entry.input }}@if ((entry.repeatCount ?? 1) > 1) { <span class=\"repeat-count\">(×{{ entry.repeatCount }})</span>}</span>\n </div>\n }\n @if (entry.result.message) {\n <div class=\"terminal-line\" [class]=\"getSeverityClass(entry.result)\">{{ entry.result.message }}</div>\n }\n }\n </div>\n</div>\n","import { Component, inject, signal } from '@angular/core';\nimport { StatusBar } from '../status-bar/status-bar';\nimport { SideMenu } from '../side-menu/side-menu';\nimport { MainContent } from '../main-content/main-content';\nimport { CommandTerminal } from '../command-terminal/command-terminal';\nimport { ThinkingService } from '../../services/thinking.service';\n\nconst MIN_TERMINAL_HEIGHT = 80;\nconst MAX_TERMINAL_RATIO = 0.6;\nconst DEFAULT_TERMINAL_HEIGHT = 160;\n\n@Component({\n selector: 'shell-root',\n imports: [StatusBar, SideMenu, MainContent, CommandTerminal],\n templateUrl: './shell.html',\n styleUrl: './shell.css',\n})\nexport class Shell {\n readonly #thinkingService = inject(ThinkingService);\n readonly isThinking = this.#thinkingService.isThinking;\n readonly terminalHeight = signal(`${DEFAULT_TERMINAL_HEIGHT}px`);\n readonly isDragging = signal(false);\n\n #startY = 0;\n #startHeight = DEFAULT_TERMINAL_HEIGHT;\n\n readonly #onMouseMove = (event: MouseEvent) => {\n const deltaY = event.clientY - this.#startY;\n const maxHeight = Math.floor(window.innerHeight * MAX_TERMINAL_RATIO);\n const newHeight = Math.min(maxHeight, Math.max(MIN_TERMINAL_HEIGHT, this.#startHeight - deltaY));\n this.terminalHeight.set(`${newHeight}px`);\n };\n\n readonly #onMouseUp = () => {\n this.isDragging.set(false);\n document.removeEventListener('mousemove', this.#onMouseMove);\n document.removeEventListener('mouseup', this.#onMouseUp);\n };\n\n onResizeStart(event: MouseEvent): void {\n event.preventDefault();\n this.#startY = event.clientY;\n this.#startHeight = parseInt(this.terminalHeight(), 10);\n this.isDragging.set(true);\n document.addEventListener('mousemove', this.#onMouseMove);\n document.addEventListener('mouseup', this.#onMouseUp);\n }\n}\n","<div class=\"shell\" [style.--terminal-height]=\"terminalHeight()\" [class.is-dragging]=\"isDragging()\">\n <shell-status-bar class=\"shell-status\" [class.disabled-zone]=\"isThinking()\">\n <ng-content />\n </shell-status-bar>\n <shell-side-menu class=\"shell-menu\" [class.disabled-zone]=\"isThinking()\" />\n <shell-main-content class=\"shell-main\" />\n <div class=\"shell-resize\" [class.dragging]=\"isDragging()\" (mousedown)=\"onResizeStart($event)\"></div>\n <shell-command-terminal class=\"shell-terminal\" [class.disabled-zone]=\"isThinking()\" />\n</div>\n","import { Component, inject, signal } from '@angular/core';\nimport { AutofillEvent, TextFieldModule } from '@angular/cdk/text-field';\nimport { Credentials, validateCredentials } from '@franzzemen/identity';\nimport { PASSWORD_REGEX, USERNAME_REGEX } from '@franzzemen/utility';\nimport { MatFormField, MatLabel } from '@angular/material/form-field';\nimport { MatInput, MatInputModule } from '@angular/material/input';\nimport { FormsModule } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatCheckboxModule } from '@angular/material/checkbox';\nimport { MatIconModule } from '@angular/material/icon';\nimport { Router } from '@angular/router';\nimport { DatePipe } from '@angular/common';\nimport { AuthenticationService } from '../../services/authentication.service';\nimport { CommandService } from '../../services/command.service';\nimport { TerminalFocusService } from '../../services/terminal-focus.service';\nimport { RegexValidatorDirective } from '../../directives/regex-validator.directive';\nimport { SHELL_APP_NAME } from '../../tokens/shell-tokens';\n\n@Component({\n selector: 'shell-login',\n templateUrl: './login.html',\n styleUrl: './login.css',\n imports: [\n FormsModule,\n MatFormField,\n MatLabel,\n MatInput,\n MatInputModule,\n MatButtonModule,\n MatCheckboxModule,\n MatIconModule,\n RegexValidatorDirective,\n TextFieldModule,\n DatePipe,\n ],\n})\nexport class Login {\n model: Credentials = { username: '', password: '' };\n submitted = false;\n hide = signal(true);\n takeover = signal(true);\n errors: { ndx: number; message: string }[] = [];\n\n protected readonly USERNAME_REGEX = USERNAME_REGEX;\n protected readonly PASSWORD_REGEX = PASSWORD_REGEX;\n protected readonly appName = inject(SHELL_APP_NAME, { optional: true }) ?? 'Application';\n\n readonly #commandService = inject(CommandService);\n readonly #terminalFocusService = inject(TerminalFocusService);\n\n constructor(\n protected authenticationService: AuthenticationService,\n protected router: Router,\n ) {}\n\n onAutofill(event: AutofillEvent, inputEl: HTMLInputElement): void {\n if (event.isAutofilled) {\n setTimeout(() => {\n const length = inputEl.value.length;\n inputEl.setSelectionRange(length, length);\n });\n }\n }\n\n clickEvent(event: MouseEvent): void {\n this.hide.set(!this.hide());\n event.stopPropagation();\n }\n\n onSubmit(event: Event): void {\n this.errors = [];\n event.preventDefault();\n this.submitted = true;\n const result = validateCredentials(this.model);\n if (result === true) {\n this.#doLogin(this.takeover());\n } else {\n for (let ndx = 0; ndx < result.length; ndx++) {\n this.errors.push({\n ndx,\n message: `${result[ndx].message ?? 'Unknown error'}: ${result[ndx].field ?? 'Unknown field'} ${result[ndx].type ?? 'Unknown type'} Expected: ${result[ndx].expected} Actual: ${result[ndx].actual}`,\n });\n }\n this.submitted = false;\n }\n }\n\n onTakeOver(): void {\n this.errors = [];\n this.submitted = true;\n this.#doLogin(true);\n }\n\n onCancelConflict(): void {\n this.authenticationService.conflictSessions.set(undefined);\n this.submitted = false;\n }\n\n #doLogin(force: boolean): void {\n this.authenticationService\n .login(this.model, force)\n .then(() => {\n this.#commandService.echoCommand(`login ${this.model.username}`);\n this.router.navigate(['/']).then(() => {\n setTimeout(() => this.#terminalFocusService.requestFocus());\n }).catch(console.error);\n })\n .catch((err) => {\n if (err !== 'conflict') {\n this.errors.push({ ndx: 0, message: typeof err === 'string' ? err : 'Unable to login' });\n }\n this.submitted = false;\n });\n }\n}\n","@let usernameRegex = USERNAME_REGEX;\n@let passwordRegex = PASSWORD_REGEX;\n<div class=\"login-container\">\n <div class=\"login-header\">\n <h2 class=\"text-text-primary\">{{ appName }}</h2>\n <p class=\"text-secondary-info\">Sign in to continue</p>\n </div>\n <form #loginForm=\"ngForm\" (ngSubmit)=\"onSubmit($event)\" class=\"login-form\">\n <mat-form-field appearance=\"outline\" class=\"login-field\">\n <mat-label>Username</mat-label>\n <input\n #usernameInput\n matInput\n placeholder=\"Enter username\"\n [(ngModel)]=\"model.username\"\n name=\"username\"\n [disabled]=\"submitted\"\n required\n regexValidator\n [regex]=\"usernameRegex\"\n (cdkAutofill)=\"onAutofill($event, usernameInput)\"\n />\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"login-field\">\n <mat-label>Password</mat-label>\n <input\n #passwordInput\n matInput\n placeholder=\"Enter password\"\n [type]=\"hide() ? 'password' : 'text'\"\n [(ngModel)]=\"model.password\"\n name=\"password\"\n [disabled]=\"submitted\"\n regexValidator\n [regex]=\"passwordRegex\"\n (cdkAutofill)=\"onAutofill($event, passwordInput)\"\n />\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n (click)=\"clickEvent($event)\"\n [attr.aria-label]=\"'Hide password'\"\n [attr.aria-pressed]=\"hide()\"\n >\n <mat-icon>{{ hide() ? 'visibility_off' : 'visibility' }}</mat-icon>\n </button>\n </mat-form-field>\n <mat-checkbox\n class=\"login-takeover\"\n name=\"takeover\"\n [checked]=\"takeover()\"\n (change)=\"takeover.set($event.checked)\"\n [disabled]=\"submitted\"\n >\n Takeover session if logged in elsewhere\n </mat-checkbox>\n <button mat-flat-button type=\"submit\" [disabled]=\"submitted\" class=\"login-button\">\n Login\n </button>\n </form>\n @if (errors.length > 0) {\n <div class=\"login-errors\">\n @for (error of errors; track error.ndx) {\n <div class=\"login-error text-loss\">{{ error.message }}</div>\n }\n </div>\n }\n @if (authenticationService.conflictSessions(); as sessions) {\n <div class=\"login-conflict\">\n @for (session of sessions; track $index) {\n <p class=\"text-secondary-info\">\n Already logged in from <strong>{{ session.appContext }}</strong>\n since {{ session.startEpoch | date:'short' }}.\n </p>\n }\n <p class=\"text-secondary-info\">Log in here and end that session?</p>\n <div class=\"login-conflict-actions\">\n <button mat-stroked-button type=\"button\" (click)=\"onCancelConflict()\">Cancel</button>\n <button mat-flat-button type=\"button\" (click)=\"onTakeOver()\">Take Over</button>\n </div>\n </div>\n }\n</div>\n","import { Component, inject } from '@angular/core';\nimport { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';\nimport { MatButtonModule } from '@angular/material/button';\n\nexport interface ConfirmDialogData {\n title: string;\n message: string;\n warningMessage?: string;\n confirmLabel?: string;\n cancelLabel?: string;\n}\n\n@Component({\n selector: 'shell-confirm-dialog',\n imports: [MatDialogModule, MatButtonModule],\n template: `\n <h2 mat-dialog-title>{{ data.title }}</h2>\n <mat-dialog-content>\n <p>{{ data.message }}</p>\n @if (data.warningMessage) {\n <p class=\"warning-message\">{{ data.warningMessage }}</p>\n }\n </mat-dialog-content>\n <mat-dialog-actions align=\"end\">\n <button mat-button (click)=\"dialogRef.close(false)\">{{ data.cancelLabel ?? 'Cancel' }}</button>\n <button mat-flat-button color=\"warn\" (click)=\"dialogRef.close(true)\">{{ data.confirmLabel ?? 'Confirm' }}</button>\n </mat-dialog-actions>\n `,\n styles: [`\n :host { display: block; }\n .warning-message { color: var(--color-warning); margin-top: 8px; }\n `],\n})\nexport class ConfirmDialog {\n readonly data = inject<ConfirmDialogData>(MAT_DIALOG_DATA);\n readonly dialogRef = inject(MatDialogRef<ConfirmDialog>);\n}\n","/*\n * Public API surface for @franzzemen/brokenstock-shell\n */\n\n// Types\nexport * from './lib/types/command.types';\nexport * from './lib/types/menu.types';\n\n// Tokens & config\nexport * from './lib/tokens/shell-tokens';\nexport * from './lib/provide-shell-config';\n\n// Guards\nexport * from './lib/guards/auth.guard';\n\n// Interceptors\nexport * from './lib/interceptors/auth.interceptor';\n\n// Directives\nexport * from './lib/directives/regex-validator.directive';\n\n// Services\nexport * from './lib/services/thinking.service';\nexport * from './lib/services/theme.service';\nexport * from './lib/services/terminal-focus.service';\nexport * from './lib/services/keyboard-shortcut.service';\nexport * from './lib/services/authentication.service';\nexport * from './lib/services/command-registry.service';\nexport * from './lib/services/command.service';\n\n// Commands\nexport * from './lib/commands/command.utils';\n\n// Components\nexport * from './lib/components/shell/shell';\nexport * from './lib/components/side-menu/side-menu';\nexport * from './lib/components/status-bar/status-bar';\nexport * from './lib/components/main-content/main-content';\nexport * from './lib/components/command-terminal/command-terminal';\nexport * from './lib/components/login/login';\nexport * from './lib/components/confirm-dialog/confirm-dialog';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1","i1.AuthenticationService","i2"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@franzzemen/brokenstock-shell",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "description": "Shared Angular shell library for Brokenstock applications",
5
5
  "author": "Franz Zemen",
6
6
  "license": "UNLICENSED",
@@ -119,7 +119,7 @@ declare class KeyboardShortcutService {
119
119
  readonly activeShortcuts: _angular_core.Signal<{
120
120
  groupId: string;
121
121
  shortcuts: ShortcutRegistration[];
122
- }>;
122
+ } | null>;
123
123
  constructor();
124
124
  registerGroup(groupId: string, shortcuts: ShortcutRegistration[]): void;
125
125
  unregisterGroup(groupId: string): void;
@@ -132,9 +132,9 @@ declare class AuthenticationService {
132
132
  #private;
133
133
  readonly authenticated: _angular_core.WritableSignal<boolean>;
134
134
  readonly authenticating: _angular_core.WritableSignal<boolean>;
135
- readonly userSession: _angular_core.WritableSignal<UserSession>;
135
+ readonly userSession: _angular_core.WritableSignal<UserSession | undefined>;
136
136
  readonly effectivePermissions: _angular_core.WritableSignal<EffectivePermissions>;
137
- readonly conflictSessions: _angular_core.WritableSignal<SessionSummary[]>;
137
+ readonly conflictSessions: _angular_core.WritableSignal<SessionSummary[] | undefined>;
138
138
  get auth(): BearerToken;
139
139
  /** Check if the current user has a specific role. */
140
140
  hasRole(roleName: RoleNames): boolean;
@@ -170,7 +170,7 @@ declare class CommandService {
170
170
  private readonly authService;
171
171
  private readonly registry;
172
172
  constructor();
173
- readonly lastResult: _angular_core.Signal<CommandResult>;
173
+ readonly lastResult: _angular_core.Signal<CommandResult | null>;
174
174
  echoCommand(input: string): void;
175
175
  pushNotification(notification: {
176
176
  message: string;
@@ -203,7 +203,7 @@ declare class SideMenu {
203
203
  readonly hasShortcuts: _angular_core.Signal<{
204
204
  groupId: string;
205
205
  shortcuts: _franzzemen_brokenstock_shell.ShortcutRegistration[];
206
- }>;
206
+ } | null>;
207
207
  readonly menuItems: _angular_core.Signal<MenuItem[]>;
208
208
  onMenuClick(item: MenuItem): void;
209
209
  toggleHelp(): void;
@@ -227,7 +227,7 @@ declare class MainContent {
227
227
  readonly activeShortcuts: _angular_core.Signal<{
228
228
  groupId: string;
229
229
  shortcuts: _franzzemen_brokenstock_shell.ShortcutRegistration[];
230
- }>;
230
+ } | null>;
231
231
  formatKey(key: string): string;
232
232
  closeShortcutHelp(): void;
233
233
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<MainContent, never>;
@@ -263,6 +263,7 @@ declare class Login {
263
263
  model: Credentials;
264
264
  submitted: boolean;
265
265
  hide: _angular_core.WritableSignal<boolean>;
266
+ takeover: _angular_core.WritableSignal<boolean>;
266
267
  errors: {
267
268
  ndx: number;
268
269
  message: string;
@@ -296,3 +297,4 @@ declare class ConfirmDialog {
296
297
 
297
298
  export { AuthenticationService, CLEAR_USAGE, CommandRegistryService, CommandService, CommandTerminal, ConfirmDialog, HELP_USAGE, KeyboardShortcutService, Login, MainContent, RegexValidatorDirective, SHELL_APP_NAME, SHELL_AUTH_URLS, SHELL_COMMANDS, SHELL_MENU_ITEMS, Shell, SideMenu, StatusBar, TerminalFocusService, ThemeService, ThinkingService, authGuard, authInterceptor, provideShellConfig, tokenize };
298
299
  export type { CommandDefinition, CommandHistoryEntry, CommandLexiconEntry, CommandResult, ConfirmDialogData, MenuItem, Severity, ShellAuthUrls, ShellConfig, ShortcutRegistration, ThemeMode };
300
+ //# sourceMappingURL=franzzemen-brokenstock-shell.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"franzzemen-brokenstock-shell.d.ts","sources":["../../src/lib/types/command.types.ts","../../src/lib/types/menu.types.ts","../../src/lib/tokens/shell-tokens.ts","../../src/lib/provide-shell-config.ts","../../src/lib/guards/auth.guard.ts","../../src/lib/interceptors/auth.interceptor.ts","../../src/lib/directives/regex-validator.directive.ts","../../src/lib/services/thinking.service.ts","../../src/lib/services/theme.service.ts","../../src/lib/services/terminal-focus.service.ts","../../src/lib/services/keyboard-shortcut.service.ts","../../src/lib/services/authentication.service.ts","../../src/lib/services/command-registry.service.ts","../../src/lib/services/command.service.ts","../../src/lib/commands/command.utils.ts","../../src/lib/components/shell/shell.ts","../../src/lib/components/side-menu/side-menu.ts","../../src/lib/components/status-bar/status-bar.ts","../../src/lib/components/main-content/main-content.ts","../../src/lib/components/command-terminal/command-terminal.ts","../../src/lib/components/login/login.ts","../../src/lib/components/confirm-dialog/confirm-dialog.ts"],"mappings":"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","names":[]}