Skip to content

Releases

v0.3.4

Choose a tag to compare

@SereinHK SereinHK released this 08 Oct 13:26

A conversation can be deleted after switching away from it — no restart needed.

Fixed

  • Deleting refused with session-live whenever the Session was resident in the process.
    ctx.sessions.get keeps answering yes for as long as DSH runs, and switching to another
    conversation does not release it — so the instruction in that message ("switch to another
    conversation and delete it then") could not be followed, and the only way through was to
    restart the application.
  • Residency is no longer a refusal. The move is attempted and the filesystem decides: a log a
    running turn still holds open fails to rename, and that is session-open, worded for
    what it is with the fix that applies — wait for the turn to finish, or restart.
  • A failed move no longer swallows its reason. A held path and a broken one need different
    words and only one of them is worth retrying, so moveToTrash returns the error and the
    route reports it. isLockedError (EBUSY, EPERM, EACCES) is the whole classification.

Verified: 31 package tests, 99 host-route checks against the built bytes (a resident
Session being moved rather than refused, the trash landing where it should, the removal
event, the classifier, and a non-lock failure keeping its real reason), 69 render and
interaction checks.

Install

dsh plugin --profile <profile> add https://github.com/SereinHK/dsh-plugin-session-delete.git

v0.3.3

Choose a tag to compare

@SereinHK SereinHK released this 08 Oct 12:08

The destructive actions in the trash are red, in the theme's own colour

  • "Empty the trash" and a row's "Delete for good" take the theme's destructive
    colour: red text on the button's outline, the same before and during the confirmation.
  • What marks the confirmation is the label (彻底删除 → 确定删除) and a line of red text in
    the dialog body naming what will go — including the conversation's own title — rather than
    a change of fill.
  • Button has no danger variant (only primary, ghost, outline, toolbar), so the red
    is read from the token the menu row's danger uses — --dsw-alias-state-error-primary —
    and follows the theme in light and dark rather than being written as a literal.
  • Pinned by checks that assert the shape rather than the pixels: the confirm control's label
    is exactly 确定删除 and not the sentence, the warning carries the danger colour, and the
    confirmation must be red and unfilled.

Verified: 31 package tests, 95 host-route checks against the built bytes, 69 render and
interaction checks.

Install

dsh plugin --profile <profile> add https://github.com/SereinHK/dsh-plugin-session-delete.git

v0.3.0

Choose a tag to compare

@SereinHK SereinHK released this 07 Oct 05:34

Stored Sessions that fell under "ungrouped" are put back where they belong.

Added

  • POST /api/session.adopt, plus the same repair once at plugin startup. A workspace
    owns Sessions through an ownership account, and the runtime attaches a Session only as
    it is created — so when a folder is added as a workspace, or renamed and added again,
    its older Sessions keep rendering under "ungrouped" and nothing in the UI can fix them.
    This attaches every stored Session whose header path resolves to a registered workspace.

Deliberately not done

  • Nothing is created, moved or deleted. An already-attached Session is skipped before the
    call (the method is idempotent anyway), a folder that no longer exists is skipped, and a
    Session whose header disagrees with the workspace path is left for the operator instead
    of being papered over.

Verified: 31 package tests, 95 host-route checks against the built bytes (adoption
among them: the mount repair, idempotence on a second run, a vanished folder, a folder
that is not a workspace, a Session with no cwd), 64 render and interaction checks.

Install

dsh plugin --profile <profile> add https://github.com/SereinHK/dsh-plugin-session-delete.git

v0.2.0

Choose a tag to compare

@SereinHK SereinHK released this 04 Oct 16:17

Release 0.2.0: removal became a move, so it can be undone

A deleted conversation now goes into a trash beside the sessions root. The rename
stays on one volume, so it is atomic — nothing is copied, and nothing is destroyed
at that point. Each entry records its workspace, title, size and when it was moved,
and stays restorable for a retention window: seven days by default, configurable per
profile with config: { retentionDays: n } on this plugin's row.

Three new routes do the rest. POST /api/session.trash lists what is in there,
purging anything past its window before it answers — so what the list shows is
exactly what can still come back. POST /api/session.restore puts one back where it
came from, refusing rather than overwriting when that name is taken. And
POST /api/session.purge destroys one entry or empties the whole trash.

In the sidebar foot, "Trash" sits beside the cleanup action, listing each entry by
title with its size and remaining days, offering Restore and Delete for good (which
asks first). The delete confirmation no longer promises permanence: it says what
actually happens, and its button reads "Move to trash".

Two things came out of building it. A purge with no record behind it used to report
success, because rm with force succeeds on a missing path — it is a 404 now. And
the client bundle is assembled into one flat factory scope, so the two dialogs
declaring the same top-level helper was a build error; the shared one moved into its
own module.

Suites: 30 package tests, 87 host-route checks against the built bytes (moving,
listing, restoring, a taken name refused, purging, expiry, a configured window,
emptying), 64 render and interaction checks.

Install

dsh plugin --profile <profile> add https://github.com/SereinHK/dsh-plugin-session-delete.git

v0.1.3

Choose a tag to compare

@SereinHK SereinHK released this 04 Oct 08:00

The cleanup shows what it removes, and the plugin checks its own assumptions.

Added

  • The durable-facts route reports each Session's title — read from the same
    projection cache the Session list itself uses — and the bytes it occupies. The
    dialog names conversations the way an operator recognises them and says what the run
    reclaims, instead of listing bare workspace paths.
  • tools/verify-runtime-contract.mjs: the plugin reads a layout it does not own (the
    JSONL backend's directory naming, the Host's projection record). Run it after a DSH
    upgrade — it decodes real logs and real records and reports, per assumption, whether
    it still holds. On the machine this was written on: 8/8, including projectKey
    reproducing the backend's own project directories across 16 real Sessions.

Changed

  • The delete path resolves both the session root and its target, and refuses a target
    whose real path falls outside the root: string containment cannot see through a link.
    Tested with a real junction pointing outside the root — the removal is refused and the
    files stay.

Verified: 28 package tests, 66 host-route checks against the built bytes (a linked
directory refused, title and size reporting, the proven/unproven cases), 48 render and
interaction checks, and the runtime contract check above.

Install

dsh plugin --profile <profile> add https://github.com/SereinHK/dsh-plugin-session-delete.git

v0.1.2

Choose a tag to compare

@SereinHK SereinHK released this 30 Sep 17:21

The blank-Session cleanup works, by asking the Host instead of guessing.

Two earlier attempts decided blankness in the page, and both were wrong for the same
reason: for a Session that is not resident, the page has no durable answer. A list row's
blank describes a live Session's first turn, and a row's projection block is loaded only
for the Session being viewed — so a cleanup run over a workspace full of empty
conversations reported "nothing to clean".

Added

  • POST /api/session.unused — reports the durable per-Session facts from the same
    projection cache the Session list itself uses: whether the stored log holds an accepted
    prompt, when the last one was, and whether the cache could answer at all.

Changed

  • The cleanup applies its policy (one-hour grace window, live Session, open Session) to
    those Host facts rather than to a display row, and loads them when the dialog opens.
  • An unprovable Session is never deleted; the dialog says how many it skipped instead of
    implying the workspace is clean.
  • A Host failure is worded as a failure, never as an empty result.

Verified: 26 package tests, 59 host-route checks against the built bytes (proven,
unproven, cache-failure and body-validation cases among them), 47 render and interaction
checks — plus a run in a real browser on a workspace holding five empty conversations,
where four were listed and the ten-minute-old one was held back by the grace window.

Install

dsh plugin --profile <profile> add https://github.com/SereinHK/dsh-plugin-session-delete.git

v0.1.1

Choose a tag to compare

@SereinHK SereinHK released this 30 Sep 17:21

Fixes the blank-Session cleanup, which never found anything to remove.

What was wrong. The cleanup trusted the blank flag on a Session-list row. That flag
describes a Session resident in the current process — for a Session loaded from disk it
carries no information — so every stored Session looked non-blank and a run always
reported "nothing to clean".

Fixed

  • Blankness now comes from the durable projection (sessionListMetadata, derived from the
    stored events) instead of the live list flag.
  • A row whose metadata has not arrived is treated as unproven rather than assumed:
    nothing irreversible happens on a guess.
  • The activity timestamp is floored by the durable lastPromptAt, so a row cannot look
    idler than it is.
  • The dialog's copy no longer claims empty conversations are hidden from the sidebar —
    they are listed, they simply hold nothing.
  • New cases cover the durable flag, the unproven row, and the lastPromptAt floor.

Verified: 24 package tests, 39 host-route checks against the built bytes, 43 render and
interaction checks.

Superseded by 0.1.2, which replaces the approach entirely: the page cannot answer this
question at all. See that release's notes.

v0.1.0

Choose a tag to compare

@SereinHK SereinHK released this 30 Sep 15:57

Changelog
0.1.0
First release.

Delete a conversation from every Session's ... menu (sidebar.workspaces.session.menu.item), after the shipped pin/rename/fork/archive rows, with a confirmation that names the conversation and the scope.
Clean up empty conversations at the sidebar foot: blank Sessions only, skipping the open one, anything running, and anything active inside a one-hour grace window.
The node half registers POST /api/session.delete inside Connection's authenticated /api fence. Removal covers the whole Session directory (every format generation of its log) plus its projection-cache record; a Session that is live in the process is refused with session-live. Attachments, exported files and workspace files are never touched.
Ships as a bundle (dsh.bundle.patch), so installing it inserts the plugin row without hand-editing a profile's cordis.patch.yml.
Verified on @deepseek-ai/dsh-desktop-runtime 0.2.0-rc.2: 21 package tests, 39 host-route checks against the built bytes, 42 render and interaction checks (including a refused removal, a partly failing cleanup run, and a target that went live mid-run), and 18 install-shape checks in both registration modes.