# dsh-workspace-hide

**Show or hide workspaces in the DSH sidebar.** Hidden workspaces are removed from the
sidebar and their sessions are collected into the archive, and you can bring any of them
back from **Settings → Workspace visibility** at any time.

Everything is local, reversible, and nothing is deleted: the workspace folder and its
session records always stay on disk.

> 中文文档：[`README.md`](./README.md)

---

## What it is for

### The problem

DSH's built-in "remove workspace" does not delete data either, but its mental model is
*"take it out of the list"*, and restoring one means adding the folder again.
Worse: **any approach that merely drops a workspace from the list makes its sessions fall
into the sidebar's "Ungrouped" section**, turning them into a pile of ownerless entries
(root cause: [`DESIGN.md` §1.1](./DESIGN.md#11-两层配合), in Chinese).

This plugin handles both halves at once:

- the workspace no longer appears in the sidebar;
- its sessions do **not** become a pile of ownerless "Ungrouped" entries — they are
  collected into the archive instead;
- when you unhide it, only the sessions that *"were archived because of this very hide"*
  come back.

**Sessions that were already archived before the hide are never touched by the
hide/restore cycle.**

### Usage

1. Install, then restart DSH Desktop;
2. Open **Settings**; the left rail shows **"Workspace visibility"**
   (right after "Archived sessions"). The rail is too narrow for the full wording, so the
   rail label is short while the panel title still spells it out:
   "Workspaces shown in the sidebar";
3. Each row has a switch on the right — **on = shown in the sidebar, off = hidden and its
   sessions archived**. A row you switch off sinks to the bottom of the list and shows
   "N sessions archived";
4. The header reads "N total · N shown · N hidden", and **"Show all"** clears the whole
   list and restores everything at once.

A hidden workspace does **not** disappear from the settings page — that page reads the
unfiltered list, otherwise there would be no way to undo the hide. Hidden rows show
"N sessions archived" so you can tell how many will come back.

> The switch defaults to **on**: a freshly installed plugin has nothing hidden, so every
> row is shown. Under this model there is no "newly created workspaces vanish by default"
> trap — every workspace is in the sidebar unless you switch its row off yourself.

> Before uninstalling or clearing the list, click **"Show all"** once; otherwise the
> archived sessions stay on the "Archived" page.

---

## Installation

### From npm (recommended)

```powershell
dsh plugin add dsh-workspace-hide@0.2.1
```

### From GitHub

```powershell
dsh plugin add https://codeload.github.com/SUZUNAMI/dsh-workspace-hide/tar.gz/refs/tags/v0.2.1
```

`dsh plugin add` is essentially `pnpm add` run inside the profile directory
(`~/.dsh/profiles/web`), and it writes the package name into **both** `dependencies` and
`dsh.profile.bundles`; `dsh plugin remove` clears both.

Measured behaviour of each target form:

| Form | Command | Notes |
|---|---|---|
| **npm (recommended)** | `dsh plugin add dsh-workspace-hide@0.2.1` | Shortest; only needs `registry.npmjs.org`, never touches `github.com` |
| **tarball** | `dsh plugin add https://codeload.github.com/SUZUNAMI/dsh-workspace-hide/tar.gz/refs/tags/v0.2.1` | No git, no SSH key, goes through `codeload.github.com`; measured 1.6s |
| `git+https` | `dsh plugin add git+https://github.com/SUZUNAMI/dsh-workspace-hide.git#v0.2.1` | Uses https git; needs `github.com:443` reachable |
| `github:` | `dsh plugin add github:SUZUNAMI/dsh-workspace-hide#v0.2.1` | ⚠️ **pnpm resolves this to `git+ssh://`** (see below); needs a working GitHub SSH key and `known_hosts` |
| Track `main` | `dsh plugin add https://codeload.github.com/SUZUNAMI/dsh-workspace-hide/tar.gz/refs/heads/main` | Upstream moves; not recommended |
| Local directory (when editing code) | `dsh plugin add file:C:/path/to/dsh-workspace-hide` | ⚠️ **materialised once at install time**; later source edits do not sync (see below) |

> **About the `github:` form**: pnpm resolves it to
> `git+ssh://git@github.com/<owner>/<repo>.git`, so a machine with no GitHub SSH set up
> fails with `Host key verification failed`. The tarball form has no such problem.

> **About the `file:` local-directory form (must-read if you edit the code)**: for a
> `file:` directory dependency, pnpm copies/hardlinks the files into `node_modules`
> **only at install time** and then never looks at the source again —
> `node_modules/dsh-workspace-hide` keeps the stale snapshot from that moment. This
> bit us once for real: the source had grown to 43365 B while the copy in the profile was
> still the 42010 B file, and no number of restarts changed the UI.
>
> To edit and use the plugin at the same time, replace that copy with a **directory
> junction** pointing at your working copy (a junction needs no administrator rights):
>
> ```powershell
> $dst = "$env:USERPROFILE\.dsh\profiles\web\node_modules\dsh-workspace-hide"
> Move-Item $dst "$dst.bak"                                    # back up the old copy first
> New-Item -ItemType Junction -Path $dst -Target "C:/path/to/dsh-workspace-hide"
> ```
>
> After that, editing the source takes effect on the next **restart of DSH Desktop**.
> Note that a later `pnpm install` or `dsh plugin add/remove` may turn it back into a real
> copy; just recreate the junction when that happens.

After installing, **restart DSH Desktop**, then open **Settings** — the left rail should
show "Workspace visibility".

Third-party plugins should be pinned to a tag or commit rather than tracking `main`.

### Manual installation

Add two entries to `~/.dsh/profiles/web/package.json`, then run `pnpm install` in that
directory:

```jsonc
{
  "dependencies": {
    "dsh-workspace-hide": "0.2.1"
  },
  "dsh": {
    "profile": {
      "bundles": ["...", "dsh-workspace-hide"]
    }
  }
}
```

### About dependencies: this plugin has none

**No npm dependencies and no build step.** `lib/client.js` is a hand-written
`window.__ModuleLoader__` factory, and the `react` and
`@deepseek-ai/dsh-client-ui-primitives` it `require`s are **injected** by the DSH runtime
(the latter also has a `try/catch` fallback that degrades to built-in controls). So those
two packages are **not** dependencies and should not be listed as dependencies — that
could even pull in a second copy of react.

---

## Changelog

### 0.2.1 — documentation only

Plugin behaviour is **unchanged**. This release is documentation:

- New English `README.en.md`, shipped inside the package so the npm page and the
  catalogue page can offer both languages.
- The repository and npm `description` are updated to the "show/hide" wording (they still
  carried the pre-0.2.0 phrasing).
- Install pins in the docs bumped to `0.2.1`.

### 0.2.0 — the settings switch now means "shown"

- Renamed: "Hidden workspaces" → panel title **"Workspaces shown in the sidebar"**, with
  the short rail label **"Workspace visibility"** (the rail cannot fit the full sentence
  and truncates it to "Sidebar worksp…"); a description line was added too.
- The switch is inverted: **on = shown, off = hidden**. It used to be
  "ticked = hidden", which read backwards.
- Hidden rows sink to the bottom of the list (stable sort; visible rows keep their
  relative order).
- Counts moved into the summary text: "N total · N shown · N hidden", and
  "N workspaces, all shown" when nothing is hidden.
- Button renamed: "Restore all" → **"Show all"** (enabled only when something is hidden).
- **Nothing changed underneath**: the storage format is still
  `dsh-workspace-hide.hidden.v2` (the same `hidden` list), as are the
  archive/unarchive scope, the `canRestore` hints, stale-entry handling, and
  cross-version migration. The inversion lives in exactly one place
  (`checked: hidden !== true` in `WorkspaceRow`, with `onChange` negating again).

### 0.1.3 — release plumbing and docs

Plugin behaviour is **unchanged**. This release switched publishing to GitHub Actions
OIDC trusted publishing (`.github/workflows/release.yml`, no long-lived npm token in the
repository any more) and promoted the npm install path to the recommended one — npm only
needs `registry.npmjs.org`, unlike the tarball/git forms which require `github.com` to be
reachable.

### 0.1.2 — first public release

- Hide a workspace from the sidebar; its sessions are merged into `archivedSessionIds`
  and no longer spill into "Ungrouped".
- When `@michengai/dsh-archive-manager` is present, the host layer turns on: real,
  undoable archiving. Without it the plugin degrades to a display-only layer and never
  archives for real (the core has no reverse operation — see `DESIGN.md`).
- Settings page "Hidden workspaces": per-row switch, `canRestore` hints, "remove record"
  for stale entries, "retry restore" after a failed unarchive, "Restore all".
- The list persists to `localStorage` under `dsh-workspace-hide.hidden.v2` (with
  automatic migration from v1).
- Install docs fixed: `github:` gets resolved by pnpm to `git+ssh://`, so the docs now use
  the codeload tarball instead.

---

## More documentation

How it works, its seams, known limits, the offline verification method, and the
source-level evidence from a real machine: [`DESIGN.md`](./DESIGN.md) — **Chinese only**.

## License

MIT
