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

# DSH Tauri Panel

> Understand the desktop sidebar shell, panel action slot, and stable panel content protocol.

`dsh-tauri-panel` is the shared entry point for desktop UI extensions. It provides one
sidebar layout and lets other plugins add panels without copying the sidebar implementation.

## Sidebar structure

The sidebar preserves official `sidebar.workspaces`, `sidebar.footer.action`, and
`sidebar.settings` slots and adds:

* the new-session action;
* the `sidebar.panel.action` list slot for consistent third-party entries;
* shared wide/compact state and active styling.

## `panel.protocol`

| Interface                  | Purpose                                                                             |
| -------------------------- | ----------------------------------------------------------------------------------- |
| `ActionItem`               | Creates a sidebar item with consistent styling, collapse behavior, and active state |
| `renderPanelContent(spec)` | Replaces the official conversation area with extension content                      |
| `closePanelContent()`      | Closes extension content and restores the official conversation view                |

Extensions provide only their icon, label, identifier, and content. They do not need to
depend on generated CSS classes or copy the official sidebar.

## Minimal example

The following client plugin registers a Projects entry in `sidebar.panel.action`. Clicking
it replaces the conversation area with custom content:

```tsx theme={null}
import type { ReactElement } from 'react'
import type { PanelProtocol } from 'dsh-tauri-panel/client'

const PANEL_SLOT = 'sidebar.panel.action'
const PANEL_SERVICE = 'panel.protocol'

function ProjectPanel(): ReactElement {
  return <div>Project panel content</div>
}

export function apply(ctx): void {
  ctx.slots.inject(PANEL_SLOT, () => {
    const panel = ctx.reflect.get(PANEL_SERVICE) as PanelProtocol | undefined
    if (panel === undefined)
      return () => {}

    const { ActionItem, renderPanelContent } = panel

    function renderProjectPanel(): void {
      renderPanelContent({
        id: 'project-panel',
        render: ProjectPanel,
      })
    }

    function Action(): ReactElement {
      return (
        <ActionItem id="project-panel" onClick={renderProjectPanel} icon={<ProjectIcon />}>
          Projects
        </ActionItem>
      )
    }

    return ctx.slots.register(
      {
        name: PANEL_SLOT,
        id: 'project-panel-action',
        registrant: 'my-plugin',
        inject: () => ({}),
      },
      Action,
    )
  })
}
```

### Return to a conversation

When an action inside the panel needs to open a conversation, close the extension content first:

```tsx theme={null}
panel.closePanelContent()
sessions.open(sessionId)
```

A production plugin should safely handle a missing slot or service and return the matching
disposer when it is unloaded. See `dsh-tauri-panel-extension` for a complete implementation.

## Current consumer

`dsh-tauri-panel-extension` is a complete consumer. It adds the Extensions entry through
the protocol and renders Skills/MCP management content.

[View source](https://github.com/dsh-tauri-desk/dsh-tauri-plugins/tree/main/packages/dsh-tauri-panel)
