Repository navigation
Releases
v0.1.4
0.1.4
This patch closes the Git skill write boundaries before publishing the updated project branding.
- Validate all tree entries before writing; refuse Windows traversal/drive/alternate-stream syntax, device aliases, case collisions, symbolic links and gitlinks.
- Bind HTTP updates to the full commit ID from the displayed preview and pin that commit during execution. Changed revisions or local file digests require a new preview.
- Protect registry edits, Git updates/restores and snapshot restores with one exclusive filesystem lock across host processes; protect cache fetches separately. Locks are never stolen automatically.
- Recheck the live tree before the staging swap so manual edits are preserved.
- Include both README languages, linked banner/feature assets and artwork notices in the actual npm package.
The update HTTP contract now requires expectedRevision; the bundled client supplies it together with source revision and digest evidence. See Git write safety for refusal and stale-lock recovery details. No account/profile format or Node/DSH engine range changes.
Validation records retain failing original regressions, passing repairs and the full cross-platform/Node matrix. Registry publication, GitHub assets, market deployment and local activation are independently verified after source merge.
dsh-version-manager 0.1.3
What changed
A path-safety fix, found by adding the first tests for a module that had none.
lib/host/operations.js had no test coverage, and neither did lib/host/locate.js.
Writing the first test for the operation journal turned up a real defect: the
encoder that turns a host-supplied name into a directory name returned ..
unchanged, so path.join(root, '..') would climb out of the plugin's own store.
Four modules each carried their own copy of that encoder.
- The encoder now lives in one module,
lib/host/segment.js, and treats a name
made only of dots as characters rather than a path. Nothing else about the
encoding changed:desktop→desktop,team/blue→team%2Fblue,
@deepseek-ai/dsh-base→@deepseek-ai%2Fdsh-base. A test pins those, because
a stricter alphabet would silently strand every snapshot and journal already
on disk. Verified against the names in a real acceptance home: identical. - Skill names get the opposite treatment. They are already directory names and
may be any script, sosafeSegmentaccepts them verbatim or refuses them
instead of transliterating them to ASCII. - The Git registry file keeps its narrower alphabet on purpose: it already ends
in.json, so it cannot traverse, and widening it would make an existing
registry read as empty.
Tests: 109 → 141. The additions cover the operation journal (state machine,
recovery_required staying unresolved, junk files not hiding good records,
profiles not sharing a journal), host location (profile copy before host copy,
unreadable manifest as null), and the encoder itself.
Install
dsh plugin --profile <profile> add dsh-version-manager@0.1.3
The panel needs the webServer service, which comes from
@deepseek-ai/dsh-web-app. A Desktop profile already carries it; a profile
created from scratch with dsh plugin add does not, and the plugin will sit at
pending (waiting for service: webServer) until it is added.
Verification
npm test— 141 pass, 0 fail, no network and no host.- CI — six jobs, Ubuntu/Windows/macOS × Node 22/24, all green on
2950359. git diff --check— clean.- Published tarball re-downloaded from the registry and compared file by file
against this commit: 20 files, 0 differences,version = 0.1.3,
sha1 f9ecb51ae970fa0741e404a3867916051a65bffb.
Honest limits
Unchanged from 0.1.2: a snapshot is not a profile backup, a Skill snapshot is a
copy rather than a version, the registry host is often not recorded by the
lockfile, compatibility is only what a package declares about itself, Skill
writes are one direction per flow, Git-managed Skills need git on PATH, and
only Windows has been tested. See the README for the full list.
dsh-version-manager 0.1.2
What changed in 0.1.2
Snapshot retention is now visible, and removal is yours to ask for.
0.1.1 kept every snapshot and never said how many there were. A target's list could
grow without bound, and the only statement about the limit was a constant in the
source. That is the wrong shape for a version manager: a limit nobody can see is not
a limit.
GET /overviewnow returnsretention: {limit, stored, beyondLimit, oldestBeyond, pruning}for every row.- The panel states the counts in words — "22 份快照,其中 2 份超出每个目标保留的 20
份。超出的不会自动删除,仍然可以恢复。" — and badges each row past the limit. POST /snapshots/prune {targetId, confirm}deletes exactly the overflow for one
target, after a confirmation that names how many files it will touch. Snapshots
inside the limit are never touched, and every removed file is listed in the
response.
The plugin still never prunes on its own. The default remains "keep too much".
Documentation P4 left open is now written: measured latency for /overview and
/skills in a real host, what the on-disk caches are and who owns them, the
retention contract, a troubleshooting table keyed by the stable error codes the
routes return, and the verified upgrade / uninstall / disable procedure.
Install
dsh plugin --profile <profile> add dsh-version-manager@0.1.2The panel plugin needs a webServer service, which comes from
@deepseek-ai/dsh-web-app. A desktop-initialized profile already carries that bundle;
a bare profile created with dsh plugin add does not, and the entry reports
pending (waiting for service: webServer) until you add it. Details in the README.
Verification
- 109 unit and integration tests, no network and no host.
- CI: six jobs, ubuntu / windows / macos × Node 22 and 24 — all green on the
release commit. - A real Desktop host (0.2.2-rc.1, Electron 44.7.0, Node 24.21.0, Windows 11) in a
throwawayDSH_HOME:- retention rendered live:
22snapshots,2past the 20 limit, both badged, the
line stated the numbers, and the button appeared; - the confirmation named the target and the count before acting;
- after confirming, the store went
22 → 20, the overflow label disappeared, and
the row read "20 份快照,未超过每个目标保留的 20 份。"; - the whole plugin lifecycle — install, enable, disable via
cordis.patch.yml,
uninstall, and reinstall — was exercised there; nine snapshots survived the
uninstall, and the 11-snapshot history came back after reinstalling.
- retention rendered live:
- Published artifact re-downloaded and compared: 19 files, 0 differences against
the release commit, nothing extra in the tarball.
Honest limits
Unchanged from 0.1.1, and still true:
- A snapshot is not a profile backup — a restore reinstalls one package; it does not
revert ranges, the lockfile, config overlays, or the dependency tree. - The registry host is often unknown; pnpm records a tarball URL for only some packages.
- Compatibility reflects the package's own declaration. No declaration reads as "no
requirement stated", never as a pass. - Skill writes are one direction per flow. A Git-managed Skill needs
gitonPATH. - Pruning is manual and permanent — that is the point of the confirmation.
- Tested as a real host on Windows only. Linux and macOS are covered by the test
suite, not by a running Desktop.
dsh-version-manager 0.1.1
Patch release. The panel was making a claim it could not support, and this fixes the wording rather than the behaviour it describes.
What was wrong
The summary line read "26 entries, 2 updatable". Two things were true at once: the number came from "the host would accept a write for this entry", and dsh-version-manager itself had /versions answering stable: [] — no newer version existed at all. The panel counted writable entries and called them updatable. That is exactly the failure mode this plugin documents itself as avoiding: reporting a thing as verified when it was never checked.
What changed
recoverabilitynow reportswritable/read_onlyinstead ofupdatable/read_only. "Writable" is the only claim the row supports: the host would accept an update. Whether a newer version exists is a separate question, answered per target by the version check and never assumed.- The summary line reads "26 entries, 1 writable", and the filter tab is "Writable" / 可写入.
- A read-only entry's tooltip no longer says "this entry cannot be updated" (which reads like the package is broken). It says "The host keeps this entry read-only, so no update is offered" — naming the host decision, which is what actually happened.
No behaviour changed: the same entries are offered the same actions.
Verification
npm test— 104 pass, 0 fail.- CI — 6/6 jobs green on the release commit
d7a8237(ubuntu / windows / macos × Node 22 / 24). - Real host — DSH Desktop 0.2.2-rc.1 (Electron 44.7.0, Node 24.21.0), Windows, into a throwaway
DSH_HOME. The published 0.1.1 artifact was installed from the registry and exercised: panel summary reads "26 个条目,1 个可写入"; the 全部 / 可写入 / 只读 filters each show the expected rows; the update and restore loop ran end to end (dsh-update-checker1.7.2 → 1.7.3 → 1.7.2, snapshot before each write,unresolved: []). - Published artifact — downloaded independently from
https://registry.npmjs.org/dsh-version-manager/-/dsh-version-manager-0.1.1.tgz, 84307 bytes, SHA2567E68666CC20970719BD1231F3E0E8D4735B88202F25E0BD5EB66B25313391D1C, SHA172cb6ecdac51b18ad74470a5cf89523f7208c15f. All 19 files match repository HEAD byte for byte, and the installed copy matches the published tarball byte for byte.
Install
dsh plugin --profile <profile> add dsh-version-manager@0.1.1Honest limits
Unchanged from 0.1.0: a snapshot is not a profile backup; the registry host is often unknown from the lockfile; compatibility uses only the package's own declaration; Skill writes are one direction per flow; Git-managed Skills need git on PATH; only Windows Desktop has been exercised in a real host.
dsh-version-manager 0.1.0
First release of dsh-version-manager — see what is installed in a DSH profile, preview updates, snapshot before writing, and roll one plugin back to a version it actually was.
Install into a profile you control:
dsh plugin --profile <profile> add dsh-version-manager@0.1.0
What it does
- Plugins tab — every bundle in the profile with its installed version, the spec the profile records, the registry it came from (or why that is unknown), whether it is loaded, and what its own compatibility declaration says.
Officialand read-only rows are marked rather than hidden. - Update preview — checks a target and separates stable releases from prereleases, so a prerelease is never offered as the obvious next step.
- Snapshots — a fingerprint of the installed tree plus the provenance needed to put the same version back.
- Single-target update — snapshot → hand the exact version to the host → read the version back → record the transitions. One target at a time; nothing is batched.
- Restore — returns a target to a version the profile recorded, verified by reading the version back.
- Skills tab — the Skills the host actually scans, with a content fingerprint and the Git revision when the directory is inside a checkout. A Skill has no version number, and the panel does not pretend it has one.
- Git-managed Skills — register a repository plus an exact subpath, then move that directory between commits and back. The plugin keeps its own bare cache and never runs Git inside your checkout.
Verification
- 104 tests, no network and no host required.
- CI on Linux, Windows and macOS against Node 22 and 24, all green.
- Driven end to end in a real DSH Desktop 0.2.2-rc.1 on Windows against a throwaway
DSH_HOME: update1.7.2 → 1.7.3, restore back, Git Skill8569b20 → c3d0909and back, and a hand-edited directory refused for update while a restore stayed possible.
The published tarball was downloaded again after release and compared byte for byte against the repository at the release commit: 19 files, no differences.
Honest limits
- A snapshot is not a profile backup. It restores a version, not configuration, dependency trees or agent presets.
- The registry host is often unknown, because the lockfile records no tarball URL for many packages.
- Compatibility is reported from the package's own declaration; an absent declaration is shown as such, not as a pass.
- Skill writes go one direction per flow — a snapshot restore swaps bytes, a Git update swaps commits. Neither merges.
- Git-managed Skills need
gitonPATH. - Tested on Windows only.
Full detail, including the refusal reasons and the routes, is in the README.