@franzzemen/brokenstock-shell 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -32,6 +32,23 @@ import { MatCheckboxModule } from '@angular/material/checkbox';
32
32
  import * as i1$2 from '@angular/material/dialog';
33
33
  import { MAT_DIALOG_DATA, MatDialogRef, MatDialogModule } from '@angular/material/dialog';
34
34
 
35
+ /**
36
+ * Does `url` fall inside any of `patterns`? Query string and fragment are
37
+ * stripped; a pattern matches when the path equals it or continues past it at
38
+ * a `/`; a `:param` segment matches any one non-empty segment. Same rule as
39
+ * the lexicon's `matchesRoute`, tested there and here.
40
+ */
41
+ function matchesRoute(url, patterns) {
42
+ const path = url.split('?')[0].split('#')[0].replace(/\/+$/, '') || '/';
43
+ const segments = path.split('/');
44
+ return patterns.some(pattern => {
45
+ const want = pattern.replace(/\/+$/, '').split('/');
46
+ if (want.length > segments.length)
47
+ return false;
48
+ return want.every((w, i) => (w.startsWith(':') ? segments[i].length > 0 : w === segments[i]));
49
+ });
50
+ }
51
+
35
52
  const SHELL_APP_NAME = new InjectionToken('SHELL_APP_NAME');
36
53
  const SHELL_MENU_ITEMS = new InjectionToken('SHELL_MENU_ITEMS');
37
54
  const SHELL_AUTH_URLS = new InjectionToken('SHELL_AUTH_URLS');
@@ -2557,6 +2574,7 @@ class FaqCommand {
2557
2574
  this.description = 'Open the in-app FAQ help system';
2558
2575
  this.usage = FAQ_USAGE;
2559
2576
  this.requiresAuth = false;
2577
+ this.scope = 'global';
2560
2578
  this.argsSchema = z.array(z.string()).max(50);
2561
2579
  }
2562
2580
  execute(args) {
@@ -2716,6 +2734,7 @@ class CommandService {
2716
2734
  ...(ngDevMode ? [{ debugName: "helpOverlay" }] : /* istanbul ignore next */ []));
2717
2735
  this.authService = inject(AuthenticationService);
2718
2736
  this.registry = inject(CommandRegistryService);
2737
+ this.router = inject(Router);
2719
2738
  this.lastResult = computed(() => {
2720
2739
  const h = this.history();
2721
2740
  return h.length > 0 ? h[h.length - 1].result : null;
@@ -2845,9 +2864,12 @@ class CommandService {
2845
2864
  ' help — List available commands',
2846
2865
  // Unavailable commands stay listed, annotated. Removing them would make
2847
2866
  // the CLI look broken rather than gated.
2867
+ // A command scoped to another screen stays listed too, with its screen
2868
+ // named rather than hidden (trades-tree.prd.md D31): hiding it would
2869
+ // read as a broken CLI.
2848
2870
  ...registered.map(c => {
2849
2871
  const availability = c.isAvailable?.();
2850
- const suffix = availability && !availability.ok ? ` [unavailable — ${availability.reason}]` : '';
2872
+ const suffix = availability && !availability.ok ? ` [unavailable — ${availability.reason}]` : this.#scopeSuffix(c.scope);
2851
2873
  return ` ${c.name} — ${c.description}${suffix}`;
2852
2874
  }),
2853
2875
  ];
@@ -2896,6 +2918,19 @@ class CommandService {
2896
2918
  if (hasHelp) {
2897
2919
  return { success: true, message: def.usage, timestamp: new Date(), isHelp: true };
2898
2920
  }
2921
+ // Screen gate (trades-tree.prd.md D30). A command bound to state only one
2922
+ // screen sets is refused off that screen with the screen named, the way
2923
+ // `tab` always did on its own. A command that navigates to its screen is
2924
+ // never refused here — declaring its routes is what lets `help` say where
2925
+ // it lives, and taking the user there is the handler's job (D32).
2926
+ if (def.scope !== 'global' && def.scope.elsewhere === 'refuse' && !matchesRoute(this.router.url, def.scope.routes)) {
2927
+ return {
2928
+ success: false,
2929
+ message: `'${command}' works on ${def.scope.screen}.`,
2930
+ severity: 'error',
2931
+ timestamp: new Date(),
2932
+ };
2933
+ }
2899
2934
  // Readiness gate. Deliberately ahead of argument validation: "you can't use
2900
2935
  // this yet, here's why" is more useful than a complaint about the arguments
2901
2936
  // of a command that wouldn't have run anyway.
@@ -2926,7 +2961,14 @@ class CommandService {
2926
2961
  // user decides whether it's worth unlocking. The gate is noted, not enforced.
2927
2962
  const availability = def.isAvailable?.();
2928
2963
  const note = availability && !availability.ok ? `\n\nCurrently unavailable — ${availability.reason}` : '';
2929
- return { success: true, message: def.usage + note, timestamp: new Date(), isHelp: true };
2964
+ const where = def.scope === 'global' ? '' : `\n\nWorks on ${def.scope.screen}.`;
2965
+ return { success: true, message: def.usage + where + note, timestamp: new Date(), isHelp: true };
2966
+ }
2967
+ /** `help`'s annotation for a command scoped to a screen other than the current one. */
2968
+ #scopeSuffix(scope) {
2969
+ if (scope === 'global' || matchesRoute(this.router.url, scope.routes))
2970
+ return '';
2971
+ return ` [${scope.screen}]`;
2930
2972
  }
2931
2973
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: CommandService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2932
2974
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: CommandService, providedIn: 'root' }); }
@@ -3358,7 +3400,12 @@ class Login {
3358
3400
  onTakeOver() {
3359
3401
  this.errors = [];
3360
3402
  this.selected.set(new Set());
3361
- this.#commandService.execute('login --force');
3403
+ // ⚠ This used to hand the terminal `login --force`, with no username or
3404
+ // password on it — the terminal's login command reads its credentials from
3405
+ // the words typed after it, found none, and answered "Invalid syntax". The
3406
+ // credentials the user already typed are on this form; sign in with them,
3407
+ // the same way the other two buttons here do.
3408
+ this.#doLogin(true);
3362
3409
  }
3363
3410
  onSignInAsWell() {
3364
3411
  this.errors = [];
@@ -3458,5 +3505,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImpor
3458
3505
  * Generated bundle index. Do not edit.
3459
3506
  */
3460
3507
 
3461
- export { AuthenticationService, CLEAR_USAGE, CommandRegistryService, CommandService, CommandTerminal, ConfirmDialog, FAQ_CONTENT_LOADER, FAQ_DEV_EDITOR, FAQ_DEV_MODE, FAQ_DEV_WORKSPACE_ROOT, FAQ_PUBLIC_PUBLISHER, FAQ_PUBLIC_SITE_BASE_URL, FaqAuthoringPanel, FaqHistoryService, FaqMarkdownRendererService, FaqModal, FaqService, HELP_USAGE, HttpFaqContentLoader, KeyboardShortcutService, Login, MainContent, PublicFaqIndex, PublicFaqPage, PublicFaqToc, RegexValidatorDirective, SESSION_TOKEN_KEY, SHELL_APP_NAME, SHELL_AUTH_URLS, SHELL_COMMANDS, SHELL_MENU_ITEMS, SHELL_POST_LOGIN_ROUTE, SHELL_SHARED_SESSION, SessionTokenStore, Shell, SideMenu, StatusBar, TerminalFocusService, TerminalVisibilityService, ThemeService, ThinkingService, audienceAllowed, authGuard, authInterceptor, buildFallbackChain, decideRenewal, guestGuard, provideShellConfig, tokenize };
3508
+ export { AuthenticationService, CLEAR_USAGE, CommandRegistryService, CommandService, CommandTerminal, ConfirmDialog, FAQ_CONTENT_LOADER, FAQ_DEV_EDITOR, FAQ_DEV_MODE, FAQ_DEV_WORKSPACE_ROOT, FAQ_PUBLIC_PUBLISHER, FAQ_PUBLIC_SITE_BASE_URL, FaqAuthoringPanel, FaqHistoryService, FaqMarkdownRendererService, FaqModal, FaqService, HELP_USAGE, HttpFaqContentLoader, KeyboardShortcutService, Login, MainContent, PublicFaqIndex, PublicFaqPage, PublicFaqToc, RegexValidatorDirective, SESSION_TOKEN_KEY, SHELL_APP_NAME, SHELL_AUTH_URLS, SHELL_COMMANDS, SHELL_MENU_ITEMS, SHELL_POST_LOGIN_ROUTE, SHELL_SHARED_SESSION, SessionTokenStore, Shell, SideMenu, StatusBar, TerminalFocusService, TerminalVisibilityService, ThemeService, ThinkingService, audienceAllowed, authGuard, authInterceptor, buildFallbackChain, decideRenewal, guestGuard, matchesRoute, provideShellConfig, tokenize };
3462
3509
  //# sourceMappingURL=franzzemen-brokenstock-shell.mjs.map