# dsh-command-palette

[中文](README.md) | English

[![npm](https://img.shields.io/npm/v/dsh-command-palette)](https://www.npmjs.com/package/dsh-command-palette)
[![stars](https://img.shields.io/github/stars/chenyangcun/dsh-command-palette?style=flat)](https://github.com/chenyangcun/dsh-command-palette)

A keyboard-first command palette for standard DeepSeek Harness (DSH). Double-tap Shift to search and open sessions, workspaces, settings pages, available features, or reusable custom commands.

## Install

```sh
dsh plugin --profile web add dsh-command-palette
```

Restart the current DSH Web process after installation, then open **Settings → Command Palette** to manage custom commands.

## What you get

- **Double-Shift trigger** — listens only in the focused DSH Web window and does not register a system-wide shortcut
- **Recent sessions** — shows the six most recently updated valid sessions by default
- **Session search** — searches titles, working directories, Agent presets, and session IDs
- **Workspace switching** — starts a session in the selected workspace directly from the palette
- **Settings navigation** — discovers registered DSH settings sections and opens the selected page directly
- **Custom commands** — saves frequently used prompts and either creates a session each time or reuses a dedicated session
- **Workspace binding** — chooses the workspace used when a custom command creates a session
- **Provider API** — lets other Client plugins register commands or trigger the palette

## Use

1. Double-tap Shift inside the DSH Web window.
2. Type to filter commands.
3. Use `↑` / `↓` to select, Enter to run, and Esc to close.
4. Add, edit, or remove custom commands under **Settings → Command Palette**.

The palette reads the current settings-section registry whenever it opens, so settings pages added by other plugins automatically appear in the **Settings** group.

When **Reuse dedicated session** is enabled, the first run creates and stores a session binding. Later runs continue in that session. If the bound session is archived or unavailable, the plugin creates a replacement automatically.

## Standard DSH and extension API

This package does not depend on Electron, a DSH Desktop preload, or a `window.dshDesktopCommandPalette` global. Sessions, workspaces, settings, and UI use standard DSH Client services.

The plugin provides a `commandPalette` service in the Client Context. Enhancement plugins can register additional commands:

```js
exports.inject = ['commandPalette']

exports.apply = (ctx) => {
  ctx.inject(['commandPalette'], (scope) => {
    scope.effect(() => scope.commandPalette.registerProvider({
      id: 'my-plugin',
      collect: () => [{
        id: 'open-dashboard',
        group: 'features',
        icon: '⌘',
        title: 'Open dashboard',
        subtitle: 'Provided by an enhancement plugin',
        keywords: ['dashboard'],
        run: () => openDashboard()
      }]
    }))
  })
}
```

Service API:

| Method | Purpose |
| --- | --- |
| `registerProvider(provider)` | Registers a command provider and returns a disposer |
| `collect(context?)` | Collects commands from every registered provider |
| `open()` | Opens the palette |
| `close()` | Closes the palette |
| `toggle()` | Toggles the palette |
| `isOpen()` | Returns the current open state |
| `subscribe(listener)` | Observes open-state or provider changes through `{ open, revision, reason }` snapshots |

Provider IDs must be unique. Commands require at least `id`, `title`, and `run()`; the provider ID is automatically prefixed to the final command ID.

Dynamic providers may also implement `subscribe(invalidate)`. Call `invalidate()` when external state changes to make the palette collect commands again. The disposer returned by `subscribe` runs automatically when the provider is removed:

```js
{
  id: 'dynamic-plugin',
  collect: () => buildCommands(currentState),
  subscribe: (invalidate) => externalStore.subscribe(() => invalidate())
}
```

Native Desktop browser tabs, Electron IPC, and native-view coordination are outside this package. A separate Desktop enhancement plugin can add them later through this API.

## Data storage

Custom commands are stored through the DSH settings system under `command-palette.commands`. The plugin creates no separate database and reads no model credentials.

## Compatibility

- Standard DeepSeek Harness (DSH)
- `@deepseek-ai/dsh` `0.1.1-rc.2`
- The standard Web Profile

## Development

```sh
npm test
npm run check
npm pack --dry-run
```

## License

[MIT](LICENSE)

Bug reports and suggestions are welcome in [Issues](https://github.com/chenyangcun/dsh-command-palette/issues).
