> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aspfox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Command Palette

> Using the Cmd+K command palette, what commands are available, and how to add your own.

## Using the command palette

Open the command palette with **Cmd+K** on macOS or **Ctrl+K** on Windows and Linux. It opens from any page.

* **Type** to filter commands by name
* **Arrow keys** to navigate between results
* **Enter** to execute the selected command
* **Escape** to close

The palette is permission-aware: commands the current user does not have access to are not shown. An admin user sees the Admin and Users commands; a regular member does not.

## Available commands

| Command          | Group      | Required permission                    |
| ---------------- | ---------- | -------------------------------------- |
| Dashboard        | Navigation | None                                   |
| Billing          | Navigation | `tenant.billing.read`                  |
| Settings         | Navigation | `tenant.settings.read`                 |
| Members          | Navigation | `tenant.members.read`                  |
| Profile          | Navigation | None                                   |
| Admin Dashboard  | Navigation | `is_admin`                             |
| Admin Users      | Navigation | `is_admin`                             |
| Admin Tenants    | Navigation | `is_admin`                             |
| Invite Member    | Actions    | `tenant.members.invite`                |
| Switch Workspace | Actions    | None (user must have multiple tenants) |
| Manage Billing   | Actions    | `tenant.billing.manage`                |
| Sign Out         | Actions    | None                                   |
| Switch to Light  | Theme      | None                                   |
| Switch to Dark   | Theme      | None                                   |
| Use System Theme | Theme      | None                                   |

## Adding a navigation command

```typescript theme={null}
// frontend/src/components/command-palette/CommandPalette.tsx

// Navigation commands are in the navigationCommands array.
// Add your new command:
{
  id: 'nav-projects',
  label: 'Projects',
  group: 'Navigation',
  icon: FolderOpen,       // from lucide-react
  requiredPermission: Permissions.TenantProjectsRead,  // omit if no permission needed
  action: () => navigate('/projects'),
},
```

## Adding a permission-gated action command

```typescript theme={null}
// Action commands with a required permission:
{
  id: 'action-create-project',
  label: 'Create Project',
  group: 'Actions',
  icon: Plus,
  requiredPermission: Permissions.TenantProjectsManage,
  action: () => {
    setCreateProjectModalOpen(true);
    closeCommandPalette();
  },
},
```

The `requiredPermission` field is checked against the current user's JWT permissions. If the user does not have the permission, the command is filtered out before the list renders.

## Adding a command that opens a modal

```typescript theme={null}
{
  id: 'action-invite-member',
  label: 'Invite Member',
  group: 'Actions',
  icon: UserPlus,
  requiredPermission: Permissions.TenantMembersInvite,
  action: () => {
    // Close the palette first, then open the modal.
    // Opening both simultaneously causes focus trap conflicts.
    closeCommandPalette();
    setTimeout(() => setInviteModalOpen(true), 50);
  },
},
```

## Customizing the keyboard shortcut

The shortcut is set in `CommandPalette.tsx` in the `useEffect` that registers the keydown listener:

```typescript theme={null}
useEffect(() => {
  const down = (e: KeyboardEvent) => {
    if (e.key === 'k' && (e.metaKey || e.ctrlKey)) {
      e.preventDefault();
      setOpen((open) => !open);
    }
  };
  document.addEventListener('keydown', down);
  return () => document.removeEventListener('keydown', down);
}, []);
```

To change to **Cmd+P** / **Ctrl+P**:

```typescript theme={null}
if (e.key === 'p' && (e.metaKey || e.ctrlKey)) {
```

## Adding command groups

Commands are grouped by their `group` property. Groups appear as headings in the palette. To add a new group:

```typescript theme={null}
// Just set a new group name on your command object.
// The palette renders groups automatically — no group registration needed.
{
  id: 'projects-create',
  label: 'New Project',
  group: 'Projects',    // new group — renders as "Projects" heading
  icon: Plus,
  action: () => navigate('/projects/new'),
},
```

Groups appear in the order their first command appears in the `allCommands` array. Put frequently used groups (Navigation, Actions) at the top of the array.
