Skip to content

Releases: luoyuejun9/dsh-skin-rotation

v2.0.1 — the desktop app can write again

Choose a tag to compare

@luoyuejun9 luoyuejun9 released this 11 Oct 10:27

Fixes a regression introduced in 2.0.0 that made every change in the settings card fail on the desktop app with cross-site-request-rejected, while reads kept working.

What went wrong

2.0.0 required a verifiable Origin on POST. The desktop shell sends its writes without an Origin header — the host's own /api fence allows exactly that, while an attached Origin must equal Host — so the plugin refused requests the host had already accepted. The card showed a state it could never edit.

The fix

The guard now refuses only what the browser itself marks as cross-site (Sec-Fetch-Site: cross-site, which page script cannot forge), and treats localhost / 127.0.0.1 / [::1] as the same machine. This is the rule the skin manager uses and the one the host fence already enforces.

Refusals are now recorded as lastRejection (reason, method, whether an Origin was attached) in the state payload, so the next origin problem is one request away from diagnosis rather than a reproduction session.

Verified

  • Against a real DSH host: a POST without an Origin now returns 200 (it returned 403 in 2.0.0); Origin matching Host and the localhost alias both return 200; Sec-Fetch-Site: cross-site and a foreign Origin still return 403.
  • 62 tests locally and on Node 20/22/24 in CI, plus the package-tarball job.

Full detail in CHANGELOG.md.

v2.0.0 — smart skin rotation

Choose a tag to compare

@luoyuejun9 luoyuejun9 released this 11 Oct 10:13

From a random pick to a rotation system: policies, a real pool, history, and crash-safe config writes. Your existing preferences migrate automatically.

Install

dsh plugin --profile web add https://github.com/luoyuejun9/dsh-skin-rotation/releases/latest/download/dsh-skin-rotation.tgz

Added

  • Policies — random, sequential, weighted and fixed, one engine shared by boot, the route and the tests. Sequential resumes at the right position after a restart; weighted takes any non-negative finite weight and treats 0 as "not in the draw".
  • Pool — every skin reported as compatible / excluded / incompatible / unavailable. Excluding a skin is never an uninstall.
  • Recent-repeat control — avoid the last 2 or 3 successful rotations. A preference, never a blocker.
  • History — bounded, own file, ISO 8601, with trigger, mode, outcome, failing stage and reason.
  • Restore previous — back to the most recent successful skin still in the pool.
  • Crash-safe writes — a journal lets an interrupted rotation finish or roll back on the next boot, and it refuses to overwrite a patch it cannot explain.
  • State schemaVersion + migrations, and rotation presets (save / apply / delete).
  • tools/verify-package.mjs — packs, unpacks, loads from an isolated directory, rejects repo-only files and absolute developer paths; run by CI.

Fixed

  • Exclusions were dropped on every save (the Set was neither normalized nor serialized).
  • Sequential mode skipped a skin when the current one left the candidate list.
  • Recovery could roll back a hand-edited patch it had not written.

Verified

  • 59 tests locally and on Node 20/22/24 in CI, plus a package-tarball job.
  • Real-host end-to-end: startup rotation, set-mode / set-weight / set-excluded / save-preset / use-preset / rotate-now / restore-previous / reset-defaults, same-origin enforcement (403) and invalid input (400).
  • A v1 preferences file migrates to v2 with its boot guard intact.

Full detail in CHANGELOG.md.

v1.0.2

Choose a tag to compare

@luoyuejun9 luoyuejun9 released this 06 Oct 12:51

Random skin rotation for DeepSeek Harness.

Install without a build step:

dsh plugin --profile web add https://github.com/luoyuejun9/dsh-skin-rotation/releases/latest/download/dsh-skin-rotation.tgz

Highlights

  • Picks a different installed skin on every launch, never the same one twice in a row.
  • On/off switch inside Settings → Skins, plus a "shuffle now" action.
  • Only picks skins the running host will actually load (mirrors DSH's plugin admission check and honours compatibility.json grants).
  • Rewrites the shared dsh-skin managed block in both patch layers, preserving every foreign row and comment.
  • One rotation per host process: a hot reload does not re-roll, a restart does.
  • 29 tests, including a differential SemVer test against node-semver.

See CHANGELOG.md for the full list.