Skip to content
dsh.fish
Bundle

@dsh-external/dsh-session-pins

Persistent pinned-session menu for DeepSeek Harness

Source
alooshxl
stars
3 stars
License
MIT
Updated
Updated 3 days ago

Readme

# DSH Session Pins

[简体中文](README.zh.md)

`@dsh-external/dsh-session-pins` adds a persistent pinned-session menu to the
DeepSeek Harness web sidebar.

The plugin answers
[DeepSeek Harness Discussion #63](https://github.com/deepseek-ai/deepseek-harness/discussions/63),
which asks to keep valuable sessions easy to reach. Harness does not expose a
public session-row action slot, and replacing the stock session browser would
couple a plugin to private UI source. Session Pins therefore contributes one
root-scoped action through the public `sidebar.footer.action` slot. It does not
patch or replace the host.

## Compatibility status

The source, automated contracts, and package artifacts target
`@deepseek-ai/dsh@0.1.0-rc.6`. DeepSeek Harness is in developer preview, so a
new release candidate may break this plugin until compatibility is reviewed.

The automated suite includes an isolated, keyless rc.6 profile smoke: it
installs this repository through the published CLI, composes the plugin row,
boots on an ephemeral loopback port, reads the root boot manifest, and fetches
the package-name browser module route. Task 7's manual wide/rail visual
acceptance remains pending and is not claimed here.

## User experience

- **Wide sidebar:** the footer action shows a pin icon, **Pinned sessions**, and
  the current pin count.
- **Rail sidebar:** the same action is icon-only, with an accessible name and a
  delayed tooltip.
- Activating the action opens a menu above the footer. Selecting a root row
  opens a same-menu drill-down with **Open**, **Unpin**, and **Back** as
  applicable. An empty list has an explicit empty state.
- An ordinary current session can be pinned when it is non-blank and not from
  a subagent. The newest pin appears first; pinning an existing id moves it to
  the front without duplicating it. A pinned current session offers **Unpin
  current session**.
- A blank current session cannot be newly pinned. If a blank id is already
  stored, it remains removable and can be opened only while its non-subagent
  summary still resolves and workspace availability is actionable.
- A subagent current session cannot be newly pinned or opened by this plugin.
  A previously stored subagent id remains removable; a rejected open is
  contained and leaves the recovery actions usable.
- Workspace archive state is actionable only when `baselinesReady === true`,
  `phase === 'ready'`, and `state === 'idle'`. Until then, every resolvable pin
  detail omits **Open**, explains that session availability is not ready, and
  keeps **Unpin** and **Back**.
- DeepSeek Harness `0.1.0-rc.6` immediately clears an archived id selected
  through `sessions.open()` and exposes no public unarchive operation. An
  actionable archived pin therefore keeps its live title, omits **Open**,
  explains this version limitation, and remains removable.
- Session Pins does not call `sessions.open()` for an archived pin or report a
  false success. It does not use a delayed-selection workaround, private API,
  host patch, or timer.
- A stale id that no longer resolves is shown as **Unavailable: _id_**. Its
  drill-down omits **Open** but keeps **Unpin** and **Back**.
- If an open fails because the session disappears or Harness rejects it, the
  menu stays usable, announces a localized error, and preserves the unpin
  recovery path.

## Browser-local persistence

Pins are stored in `localStorage` under `dsh.session-pins.v1` as a versioned,
ordered id list. Input is validated: malformed records fall back to empty,
non-string and blank ids are removed, duplicate ids keep their first
occurrence, and at most 100 pins are retained.

Persistence is browser-local. It does not sync across devices, browser
profiles, browsers, or different origins. Same-origin tabs reconcile
through browser `storage` events while the plugin is active; the tab that
writes a change updates itself directly because browsers do not send that
`storage` event back to the writing document. If `localStorage` is blocked or
throws, pins remain usable in memory for the current page but do not survive a
reload.

## Install after release

The GitHub repository and tag are created during the release step. Run these
commands only after the referenced release exists.

Install the `v0.1.0` Git tag into the stock web profile:

```sh
dsh plugin --profile web add github:alooshxl/dsh-session-pins#v0.1.0
```

To upgrade to another Git tag, repeat `add` with that tag; do not use `update`
to select a Git ref. For example:

```sh
dsh plugin --profile web add github:alooshxl/dsh-session-pins#v0.1.1
```

For an immutable installation, replace the placeholder with the full
40-character commit SHA:

```sh
dsh plugin --profile web add github:alooshxl/dsh-session-pins#<40-character-commit-sha>
```

Remove the plugin:

```sh
dsh plugin --profile web remove @dsh-external/dsh-session-pins
```

Launch the stock web profile:

```sh
dsh web
```

The equivalent explicit launch is:

```sh
dsh --profile web
```

The package tracks reviewed `lib/` output. A Git installation therefore needs
neither an install build allowlist nor an install-time `prepare`, `install`, or
`postinstall` lifecycle.

## Security and host boundaries

- No API key or other credential is required to pin, unpin, persist, or open a
  session.
- The package does not read credential files, ship temporary browser profiles,
  or include private Harness source.
- Product behavior stays in the browser client entry. The Node entry only
  enables package registration and browser-module discovery.
- Integration uses published Harness client services and the public
  `sidebar.footer.action` slot. There is no host patch, monkey patch, or
  compatibility layer.

## Local development

Use Node 22 and pnpm 11.7.0:

```sh
git clone https://github.com/alooshxl/dsh-session-pins.git
cd dsh-session-pins
pnpm install --frozen-lockfile
```

The frozen development graph allows lifecycle scripts only for the exact
`@deepseek-ai/dsh-subprocess-local@0.1.0-rc.6` and `node-pty@1.1.0` transitive
host dependencies required to boot the published rc.6 Web profile on Linux.
Every other discovered script is denied. These development-only host packages
are not part of the packed plugin or its installation contract.

The GNU Make checkpoint is:

```sh
make fmt && make test && make lint
```

On systems without GNU Make, run its exact commands:

```sh
pnpm run format && pnpm run test && pnpm run lint
pnpm run typecheck
```

Run the complete release-oriented verification:

```sh
pnpm run build
pnpm run format:check
pnpm run typecheck
pnpm run verify:self-contained
pnpm run verify:package
git diff --check
git status --short --untracked-files=all -- lib
```

`pnpm run verify:package` performs the local dry-run package inventory
validation through a compatible package-manager invocation.

The final `git status` command must print nothing: tracked and untracked
generated-artifact drift is blocking.

## Contributing, discussion, and license

Please report defects or compatibility findings through
[GitHub issues](https://github.com/alooshxl/dsh-session-pins/issues), and send
focused changes through
[pull requests](https://github.com/alooshxl/dsh-session-pins/pulls). Feature
context remains available in
[Discussion #63](https://github.com/deepseek-ai/deepseek-harness/discussions/63).

This project is available under the [MIT License](LICENSE).

Install

dsh plugin --profile web add github:alooshxl/dsh-session-pins

Profile: web

  • This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source