dsh-workspace-mover 2.4.2 → 2.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +345 -327
- package/README.md +389 -381
- package/README_EN.md +376 -368
- package/client/client.js +2792 -2678
- package/docs/ARCHITECTURE.md +224 -224
- package/docs/compatibility/dsh-0.2.0-rc.2-2026-10-13.md +45 -45
- package/docs/compatibility/immediate-migration-2026-10-26.md +68 -68
- package/docs/compatibility/issue-11-pr-12-review-2026-11-02.md +103 -0
- package/docs/compatibility/issue-5-desktop-acceptance-2026-10-22.md +106 -106
- package/docs/compatibility/pr-review-2026-10-22.md +56 -56
- package/lib/index.js +36 -5
- package/lib/lifecycle.js +2 -2
- package/package.json +104 -104
- package/test/client-dom.test.mjs +98 -0
- package/test/core.test.mjs +73 -73
- package/test/e2e-sandbox.test.mjs +36 -1
- package/test/live-migration.test.mjs +72 -2
- package/test/release-downloads.test.mjs +102 -102
- package/test/traffic-badge.test.mjs +80 -80
package/CHANGELOG.md
CHANGED
|
@@ -1,327 +1,345 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
## [2.4.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
-
|
|
42
|
-
-
|
|
43
|
-
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
-
|
|
50
|
-
|
|
51
|
-
-
|
|
52
|
-
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
###
|
|
66
|
-
|
|
67
|
-
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
### Changed
|
|
73
|
-
|
|
74
|
-
-
|
|
75
|
-
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
-
|
|
81
|
-
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
- **
|
|
93
|
-
- **
|
|
94
|
-
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
-
|
|
102
|
-
- **
|
|
103
|
-
- **
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
- **
|
|
112
|
-
- **
|
|
113
|
-
- `
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
-
|
|
152
|
-
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
-
|
|
213
|
-
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
- **
|
|
221
|
-
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
-
|
|
231
|
-
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
- **
|
|
239
|
-
- **
|
|
240
|
-
- **
|
|
241
|
-
-
|
|
242
|
-
- Tests
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
-
|
|
249
|
-
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
-
|
|
257
|
-
-
|
|
258
|
-
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
### Fixed
|
|
263
|
-
|
|
264
|
-
-
|
|
265
|
-
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
-
|
|
290
|
-
-
|
|
291
|
-
-
|
|
292
|
-
|
|
293
|
-
## [0.
|
|
294
|
-
|
|
295
|
-
### Fixed
|
|
296
|
-
|
|
297
|
-
-
|
|
298
|
-
-
|
|
299
|
-
-
|
|
300
|
-
-
|
|
301
|
-
|
|
302
|
-
## [0.
|
|
303
|
-
|
|
304
|
-
### Added
|
|
305
|
-
|
|
306
|
-
-
|
|
307
|
-
- Move
|
|
308
|
-
-
|
|
309
|
-
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
-
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [2.4.3] - 2026-11-03
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- The client UI follows the DSH language through its official optional `locale` service (PR #12, EzraRT). The settings panel updates on locale changes; newly opened dialogs use the current language. An already open confirmation dialog keeps its original text until reopened. Hosts without the service keep the browser-language fallback; teardown removes subscriptions and dictionaries.
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- Refresh the public client Session baseline after recycle-bin restoration, backup restoration and unarchiving, so restored cold archives can appear without restarting. Keep successful restoration distinct from a later list-refresh failure. Recycle restoration explicitly reports when the original archived state is preserved.
|
|
12
|
+
- Idle resident sessions with tracked public lifecycle handles can be released and deleted to the recycle bin without restarting. Successful deletion never reloads the removed session, and clears its selected view. Running or untracked resident sessions remain protected (#11).
|
|
13
|
+
- Delete failure reloads only when an archive can still be located. If the manifest write and physical rollback both fail, preserve the relocated files and recovery record instead of deleting the recovery directory.
|
|
14
|
+
- Missing roster entries distinguish archives found elsewhere in the current storage root from unknown locations. Preserve ownership and archived entries; missing files do not prove deletion. Remove the unsupported claim that restarting automatically cleans these records (#11).
|
|
15
|
+
|
|
16
|
+
### Validation
|
|
17
|
+
|
|
18
|
+
- Desktop `0.2.1-rc.5`: user accepted `2.4.3-rc.2` deletion, recycle restoration, immediate list/sidebar recovery and continued replies; language switching and migration passed in rc.1. Running-session deletion refusal is covered by automated checks, not the host's separate Stop and archive dialog. See [review and acceptance record](docs/compatibility/issue-11-pr-12-review-2026-11-02.md).
|
|
19
|
+
- Local syntax/tests/package checks: 334 passed, 3 optional runtime checks skipped; installed DSH runtime checks: all 6 passed. Web and older-host manual acceptance remain pending.
|
|
20
|
+
|
|
21
|
+
## [2.4.2] - 2026-10-26
|
|
22
|
+
|
|
23
|
+
- Reopen the still-selected removed conversation through host navigation after migration or rollback, waiting for the old view's retained references to release before reopening. Do not change a later user selection. Replace the page-refresh hint with a fully-quit-and-restart hint for Desktop.
|
|
24
|
+
- Read titles from the live cache and current per-record checkpoints before legacy aggregate caches, fixing unnamed entries in repair/archive/preview/backup lists.
|
|
25
|
+
- Tracked idle sessions now release their public Agent lifecycle, physically migrate and reload through the host controller without a pending queue or restart. New requests are refused while the lifecycle is draining.
|
|
26
|
+
- Dragging a running session offers cancellation or explicit stop-and-move. The backend rechecks consent; it never stops a newly running task based on a stale idle preview.
|
|
27
|
+
- Fix #10: use the projection table get/put contract and align title-cache identity before publishing target membership. Failed attachment restores the source checkpoint identity.
|
|
28
|
+
- Restart once after installation/hot update to capture lifecycle handles. Untracked or unsupported live writers remain protected. Existing queue APIs remain compatible.
|
|
29
|
+
- Validation: user accepted candidate 2.4.2-rc.4 on DSH Desktop 0.2.1-rc.2: immediate movement, title preservation, continued replies without switching views, cancel while running, explicit stop-and-move, and persistence/continued replies after restart. Windows local checks: 327 passed, 2 optional host tests skipped; installed-host checks: all 4 passed. Web and the reporter's DSH 0.2.0-rc.2 environment remain unverified.
|
|
30
|
+
|
|
31
|
+
## [2.4.1] - 2026-10-22
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
|
|
35
|
+
- Synchronize version metadata and documentation badges; runtime behavior is unchanged.
|
|
36
|
+
|
|
37
|
+
## [2.4.0] - 2026-10-22
|
|
38
|
+
|
|
39
|
+
### Added
|
|
40
|
+
|
|
41
|
+
- Agent tools mover_create_workspace (register an existing folder) and mover_rename_workspace (display title only), from PR #7. Duplicate names/folder aliases are rejected. Rename asks for approval unless the calling session has full access.
|
|
42
|
+
- Sidebar edge autoscroll from PR #9, with pointer bounds, scroll limits, drag cancellation and hot-unload cleanup.
|
|
43
|
+
- pluginVersion in status and doctor output.
|
|
44
|
+
|
|
45
|
+
### Fixed
|
|
46
|
+
|
|
47
|
+
- Issue #5: also detect opening/closing JSONL writer claims even after the session leaves memory. Unknown handle backends wait safely. Keep header rewrite and relocation synchronous after the final writer check.
|
|
48
|
+
- Fresh-install scans treat only missing storage roots as empty (PR #8); permission and I/O failures remain visible.
|
|
49
|
+
- Optional tools/approval no longer disable the whole plugin. Tools follow host service load/unload; approval requests carry ACP callId. Missing approval or agent context refuses operations requiring confirmation.
|
|
50
|
+
|
|
51
|
+
- Queue resident sessions until unloading instead of mutating private writer state or frozen live headers; await backend flush before cold migration. Workspace repoint refuses resident writers before changing registry paths.
|
|
52
|
+
- Preserve existing working-directory history and append the destination directory when needed; invalidate the corresponding projection checkpoint. Unsupported sequences are rejected before migration.
|
|
53
|
+
- Restore v3/v4 backup filenames from the official header version; preserve unversioned legacy filenames.
|
|
54
|
+
- Read Portable Bundle pluginVersion from package.json.
|
|
55
|
+
|
|
56
|
+
### Validation
|
|
57
|
+
|
|
58
|
+
- Desktop `0.2.1-rc.2`: user accepted candidate `2.4.0-rc.1`; opened-session queueing, continued A2 replies while pending, migration after restart, B1/B2 replies across a second restart, destination working directory and doctor checks passed.
|
|
59
|
+
- Workspace registration, rename rejection/approval, name conflicts, no-op renames and full-access rename passed in Desktop.
|
|
60
|
+
- Windows local gate: 315 tests passed; installed official JSONL/ToolRuntime backend check passed. Sidebar autoscroll is covered by automated DOM checks; the user waived manual autoscroll acceptance.
|
|
61
|
+
- Open sessions finish migration only after their writer is unloaded or DSH is restarted. Switch to another session before restarting so Desktop does not immediately reopen the pending session.
|
|
62
|
+
|
|
63
|
+
## [2.3.0] - 2026-10-13
|
|
64
|
+
|
|
65
|
+
### Added
|
|
66
|
+
|
|
67
|
+
- Persistent busy-session migration queue with idle retries, cancellation, and individual/batch retry.
|
|
68
|
+
- Migration preview and explicit target-workspace selection, adapter diagnostics, and v3/v4/plain/Zstd format checks.
|
|
69
|
+
- Optional descendant migration and Portable Bundle export/inspection/dry-run import APIs (sandbox verified; real-runtime validation remains pending).
|
|
70
|
+
- npm weekly downloads badge and documentation of the expected filesystem adapter warning.
|
|
71
|
+
|
|
72
|
+
### Changed
|
|
73
|
+
|
|
74
|
+
- Identical content reuses a recovery snapshot, ignoring migration-only cwd changes. Changed content creates a new snapshot; every move remains in history. Legacy backup filenames remain supported.
|
|
75
|
+
- Preview displays newly required backup bytes and snapshot reuse. Retention limits count physical snapshots.
|
|
76
|
+
|
|
77
|
+
### Fixed
|
|
78
|
+
|
|
79
|
+
- Return-move workspace resolution and stale hover targets; failed or stale previews cannot execute against an earlier target.
|
|
80
|
+
- Default backup restoration chooses the newest saved snapshot.
|
|
81
|
+
- Portable Bundle space estimates include attachments and known insufficient space blocks execution.
|
|
82
|
+
|
|
83
|
+
### Validation
|
|
84
|
+
|
|
85
|
+
- User confirmed Desktop idle-session migration and snapshot reuse. Web, full runtime rollback smoke, and DSH process-restart queue recovery remain unverified; see the dated compatibility report.
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
## [2.2.0] - 2026-10-09
|
|
89
|
+
|
|
90
|
+
### Changed (behavior)
|
|
91
|
+
|
|
92
|
+
- **Batch and multi-select moves no longer guess a session id.** When the authoritative row-to-id channel (the React fiber carrying `node.id`) is unavailable, the client used to fall back to positional order and, on a title mismatch, take the *next* id in sequence. Because the official sidebar hides blank and archived rows, that fallback could shift a group by one and move a *different but valid* set of sessions — undetectable host-side. The fallback now refuses to guess: unresolvable rows are reported to the user, and a move either aborts (nothing resolvable) or proceeds with only the rows that resolved, after an explicit confirmation that names the skipped count. This is the one intentional behavior change in this release.
|
|
93
|
+
- **Workspace resolution verifies instead of trusting DOM order.** The positional fallback that mapped the *i*-th sidebar header to the *i*-th registry item is now accepted only when the header text actually matches that item's title or path; otherwise the move aborts with the existing "list out of sync" message. Previously a single hidden header (for example a workspace whose folder was moved) shifted every later index by one.
|
|
94
|
+
- **`workspace-mover` styles and dialog semantics** unchanged in appearance; dialogs gained an accessible name, initial focus, and a Tab trap.
|
|
95
|
+
|
|
96
|
+
### Added
|
|
97
|
+
|
|
98
|
+
- **`screenshots.json`**: declares the plugin's screenshots in-repository so plugin storefronts (dsh-market and peers) show them App Store style in a controlled order instead of scraping the README.
|
|
99
|
+
- **`peerDependencies`** for the official packages the plugin integrates with, declared as `*` and marked optional in `peerDependenciesMeta`. These peers are declarative only — the plugin fail-softs at runtime and reports any real degradation through `mover.status` capabilities and `mover_doctor` — so they exist for storefront metadata, not as a compatibility gate. The real floor is `engines.dsh`.
|
|
100
|
+
- **Fixed: the first attempt at those peer ranges made the host declare the plugin incompatible with `0.2.0-rc.2`.** The ranges were written in the ecosystem's "explicit prerelease branch" idiom, e.g. `>=0.0.1-rc.1 <0.1.0 || >=0.1.0-rc.1 <0.2.0-0`. npm's prerelease rule evaluates each `||` alternative as a *set* and only admits a prerelease when a comparator in that set shares the version's exact `major.minor.patch` tuple **and** carries a prerelease tag; then every comparator is checked normally. Because `0.2.0-rc.2 > 0.2.0-0`, the upper bound `<0.2.0-0` excluded **every 0.2.0 prerelease** — i.e. the plugin's own tested host line. Enumerating release lines would reproduce this on each new line (a `<0.3.0-0` bound breaks the moment 0.3 lands), so all eight peers are now `*`. A regression test asserts the declared ranges plus `engines.dsh` yield `compatible` (never `incompatible`) for every DSH line from 0.1.5-rc.1 through 1.0.0.
|
|
101
|
+
- **Storage-layout self-check.** The plugin re-implements the session-store directory encoding, and the persistence root it derives from is not a documented part of the `SessionPersistence` contract. A new read-only check reverse-derives one real session's directory from `persistence.list()` and verifies it exists; the result appears as `mover.status.capabilities.storageLayout` and as a `data-layout` check in `mover_doctor`, so a host layout change becomes a visible degraded state instead of sessions that silently cannot be found.
|
|
102
|
+
- **Archive-truncation visibility.** The rescue scan parses only the newest 400 session archives, and archived sessions are typically old — so on large libraries they could drop out of the archived list with no explanation. The archived view now reports when the underlying scan was truncated.
|
|
103
|
+
- **Client test coverage.** `test/client-dom.test.mjs` exercises the client half against a hand-rolled DOM stub (no new dependencies): workspace resolution, row-to-id mapping, the drop payload, listener teardown, dialog dismissal and the RPC failure matrix.
|
|
104
|
+
|
|
105
|
+
### Fixed
|
|
106
|
+
|
|
107
|
+
- **Client half had no teardown.** Seven document-level listeners and a `document.body` subtree `MutationObserver` were never released. The project's own hot-reload path (the desktop client disposes and recomposes the plugin fiber) could therefore stack a second copy of every listener, causing duplicate confirm dialogs, duplicate RPC calls, and two copies fighting over the same selection highlight. All listeners and the observer are now registered through the plugin context's disposal channel, and a module-level guard prevents a duplicate `apply`.
|
|
108
|
+
- **The menu observer no longer runs for the whole page lifetime.** It is connected after an ellipsis click and disconnected on injection or timeout, instead of observing every DOM mutation in the app forever.
|
|
109
|
+
- **Dead and contradictory client strings.** `ungroupedUnsupported` was never referenced. `pickEscHint` was never referenced *and* contradicted the implementation; Escape now respects the copy (it does not clear the multi-selection while a text input has focus). Two hard-coded English strings that leaked into the Chinese UI are now localized.
|
|
110
|
+
- **Documentation drift**: the READMEs and `docs/ARCHITECTURE.md` described three agent tools while four are registered (`mover_doctor` was missing), and the compatibility section still claimed verification against `0.1.5-rc.1` while the README badge claimed `0.2.0-rc.2`. Tool tables, the compatibility boundary, and the test-suite description are now consistent and dated.
|
|
111
|
+
- **Tests 108 → 144**: 10 new client DOM cases (row/workspace resolution, drag payload, listener teardown, dialog dismissal and the RPC failure matrix, against a hand-rolled DOM stub), 13 policy/Config/peer-range cases, and host-side coverage for the storage-layout self-check, archive truncation, backup orphan GC, the unarchive dual path, setTitle decoupling, and the official-API capability flags.
|
|
112
|
+
- **Fixed a latent policy bug found while wiring the tunables**: `cleanupOldData` destructured `{ days = 30 }`, so "not supplied" became `30` and the `Number(days) || cleanupDays()` fallback could never see `undefined` — the configured cleanup age was silently shadowed by the default.
|
|
113
|
+
- **Backups taken in the same millisecond no longer overwrite each other.** `stashBackup` named files `${id}.${Date.now()}.zstd`, so two backups landing in the same millisecond produced the same name and the second silently replaced the first — the configured retention (`backupKeep`) was then not honoured, and an operation's pre-move safety copy could be lost. This is platform-dependent and was invisible on Windows: Linux exposes it readily (coarser clock granularity), which is why the `ubuntu` and `macos` CI jobs failed while `windows` passed. Backup names now carry a `-N` disambiguator only when the base name is already taken, so distinct operations always leave distinct files while deliberately re-stashing within one millisecond still collapses to one (bounded disk use). Both filename parsers (cleanup and listing) accept the optional suffix. Covered by a new policy case plus a direct same-millisecond assertion in the sandbox suite.
|
|
114
|
+
|
|
115
|
+
## [2.1.1] - 2026-10-05
|
|
116
|
+
|
|
117
|
+
### Added
|
|
118
|
+
|
|
119
|
+
- **`mover.doctor` self-check**: a read-only diagnostics endpoint, a "Doctor" button in the rescue panel, and a `mover_doctor` agent tool. ~13 checks cover host services (registry, persistence, projection cache, archive channel, agents, approval seam), agent-tool registration, data directories (recycle bin, backups, move history, task records), pending manual-recovery records, and workspace folder presence — each reported as pass / warn / fail with details and a summary. Intended for after DSH upgrades: see what is degraded before attempting anything else. Stays sub-second (no full scan), never mutates, and never throws — degraded hosts get fail/warn checks instead of errors.
|
|
120
|
+
- **Install and trust assets in the README**: the npm one-liner featured under the tagline (a `dsh://plugin/install` deep-link button was attempted and removed — GitHub's sanitizer strips custom-protocol links and rewrites the anchor to the badge image itself; enter through dsh.so for one-click install on Hub-aligned clients), a dsh.so risk badge (listed, L5 run-tested, risk low), a dsh-plugin-registry listing badge, and a "DSH tested 0.2.0-rc.2" badge.
|
|
121
|
+
- **Compatibility report**: `docs/compatibility/dsh-0.2.0-rc.2-2026-10-04.md` records the real desktop verification (shared data home, in-app plugin install, drag move, dialog, hot-reload fix, agent tools) and the web-profile regression status; future DSH adaptations add a dated copy each.
|
|
122
|
+
- **Safety Ledger**: the security-guarantees section is now branded around the backup-first pipeline (backup → stepwise rollback → post-move verification → recovery ledger) with an explicit never-does list (no git writes, no unbacked edits, no silent data loss, no unconfirmed destructive actions, no uploads — the plugin makes no network requests).
|
|
123
|
+
- Tests 105 → 108 (doctor all-green in sandbox, degraded-registry fail/warn behavior, recovery-record warning; agent-tool roster updated).
|
|
124
|
+
|
|
125
|
+
## [2.1.0] - 2026-10-04
|
|
126
|
+
|
|
127
|
+
### Added
|
|
128
|
+
|
|
129
|
+
- **Agent tools**: the plugin now registers three model-callable tools through the official `dsh-tools` registry — `mover_list_sessions` (read-only listing of workspace groups and sessions with their rescue statuses, for resolving a user-named group or conversation into exact ids), `mover_move_session` (moves one session through the same locked, backup-first, verified pipeline the panel uses), and `mover_repair_sessions` (one accounting-only repair pass). Tools are plain zero-dependency tool definitions; registration is skipped silently on hosts without `dsh-tools`, leaving the panel and drag flows untouched.
|
|
130
|
+
- **User approval for mutating tools**: `mover_move_session` and `mover_repair_sessions` request an explicit user decision through the host approval seam (`dsh-user-approval`, mounted by dsh-base) before touching anything; a denial, dismissal, or unavailable answerer fails closed with a clear message, and approval-seam errors also block the call. Cancellation propagates cooperatively into the RPC layer, which finishes any in-flight rollback before stopping.
|
|
131
|
+
- `mover.status` reports an `agentTools` capability flag.
|
|
132
|
+
- Tests 97 → 104 (tool registration and capability flag, listing composition, approval-gated move success, fail-closed outcomes for denied / cancelled / unavailable / seam-error, error-code passthrough with no approval round-trip for invalid input, repair with approval).
|
|
133
|
+
|
|
134
|
+
### Fixed
|
|
135
|
+
|
|
136
|
+
- **Opaque confirm dialog on the desktop (0.2).** The desktop theme defines `--dsw-specific-menu` as a translucent glass color, so the cross-workspace confirm card blended with the text underneath. The card now forces the themed color to full alpha via CSS relative-color syntax (browsers without support keep the previous translucent behavior).
|
|
137
|
+
- **Desktop (0.2) hot-reload no longer breaks moves.** The client half accessed `ctx.connection` lazily on every RPC. After the desktop app hot-reloads or recomposes its client, the plugin's old cordis fiber is disposed, and that access throws `cannot get required service "connection" in inactive context` — surfacing as a failed-move toast even though nothing was wrong with the session. The connection service instance is now captured once at apply time (while the context is active) and reused for every call; if capture is not possible, a clear "refresh the page" message replaces the internal error in both the drag toast and the rescue-panel note paths (new `contextStale` strings, zh/en).
|
|
138
|
+
|
|
139
|
+
## [2.0.3] - 2026-09-21
|
|
140
|
+
|
|
141
|
+
### Engineering
|
|
142
|
+
|
|
143
|
+
- First publish to the public npm registry as `dsh-workspace-mover` (installs via `dsh plugin --profile web add dsh-workspace-mover`).
|
|
144
|
+
- Local quality gate `npm run check` (syntax + tests + pack dry-run); CI runs the same steps on ubuntu / windows / macos × Node 22/24.
|
|
145
|
+
- README (zh/en): CI / npm version / plugin / DSH engines badges and a host compatibility matrix (`0.1.5-rc.1` / `rc.2`; `0.1.6-alpha` pending verification).
|
|
146
|
+
- CONTRIBUTING: release checklist keeps `package.json` version, CHANGELOG, and git tags aligned; PR template requires `npm run check`.
|
|
147
|
+
|
|
148
|
+
## [2.0.2] - 2026-09-13
|
|
149
|
+
|
|
150
|
+
- Fixed GitHub Traffic badge updates when a Gist patch would delete a file that is not present; the workflow now skips missing-file deletes and avoids HTTP 422 failures.
|
|
151
|
+
- Completed the architecture documentation: the RPC endpoint list and workspace projection refresh behavior now match the implementation.
|
|
152
|
+
- Published `.tgz` assets now include the architecture documentation and screenshots, and duplicate historical changelog entries were removed.
|
|
153
|
+
|
|
154
|
+
## [2.0.1] - 2026-09-12
|
|
155
|
+
|
|
156
|
+
- Compatible with DeepSeek Harness `0.1.5-rc.1`.
|
|
157
|
+
- Release downloads stay off the README until the total exceeds 10; when shown they use shields.io like the other badges instead of a gist SVG that GitHub renders as a broken text link.
|
|
158
|
+
- Host half waits for `webServer` before registering RPC, fixing boot failures on 0.1.5.
|
|
159
|
+
- Session relocation follows the highest canonical generation (`session.vN.jsonl[.zstd]`) instead of a hard-coded `session.jsonl.zstd`.
|
|
160
|
+
- Refuse conflicting operations through in-process session/workspace locks; no `session.lock` file is created.
|
|
161
|
+
- Keep full mover feature set (rescue, repoint, trash/backup, task center); official DSH still has no cross-workspace true move.
|
|
162
|
+
|
|
163
|
+
All notable changes to this project are documented here.
|
|
164
|
+
|
|
165
|
+
## [1.4.2] - 2026-09-09
|
|
166
|
+
|
|
167
|
+
### Added
|
|
168
|
+
|
|
169
|
+
- GitHub Release tags now publish a versioned `.tgz` asset and collect its download count separately from repository clones.
|
|
170
|
+
- The public README keeps only the observed GitHub clone metric; the Release downloads badge remains visually hidden until the total exceeds 10.
|
|
171
|
+
|
|
172
|
+
### Fixed
|
|
173
|
+
|
|
174
|
+
- Traffic history collection now consumes GitHub's `clones[]` response, upserts daily corrections, and labels the cumulative value with its observation start date.
|
|
175
|
+
|
|
176
|
+
## [1.4.1] - 2026-09-09
|
|
177
|
+
|
|
178
|
+
### Fixed
|
|
179
|
+
|
|
180
|
+
- **GitHub traffic history now uses the real `clones[]` response field.** The collector no longer mistakes the rolling 14-day aggregate for an all-time total.
|
|
181
|
+
- Daily clone rows are upserted by date, and the badges now distinguish observed cumulative clones from GitHub's current 14-day clone and unique-cloner window.
|
|
182
|
+
- Added deterministic traffic-response contract tests and migrated legacy state without presenting the old estimate as verified history.
|
|
183
|
+
|
|
184
|
+
## [1.4.0] - 2026-09-06
|
|
185
|
+
|
|
186
|
+
### Added
|
|
187
|
+
|
|
188
|
+
- **Concurrency guards (try-acquire locks)**: per-session and per-workspace keys now serialize every entry point — single move, batch move, trash delete / restore, backup restore, and workspace re-point. A second operation touching the same key never queues or deadlocks: it fails immediately with a stable `busy` code, and the client explains that the session is still being processed. Batch inputs are de-duplicated so one batch cannot race itself.
|
|
189
|
+
- **Stable RPC error codes**: every RPC failure now carries a machine-readable `code` — `busy / conflict / not-found / invalid-input / not-writable / insufficient-space / backup-failed / rollback-failed / corrupt-artifact / unsupported / bad-request / internal-error` — mapped at the dispatch boundary, with codes attached at the source where a message pattern would mislead (e.g. a writability-probe `EEXIST` maps to `not-writable`, not `conflict`). The client reads `error.code` first and keeps the old English-message matching only as a fallback.
|
|
190
|
+
- **Minimal recovery ledger**: any "rollback also failed" path (attach-rollback failure on move; manifest-write failure plus failed move-back on delete) writes a durable record to `$DSH_HOME/workspace-mover/recovery.json` (kind, phase, session, source / target, last error, time). The scan response carries `recoveryCount`, `mover.status` reports it, and the rescue panel shows a red "needs manual recovery" row — nothing is auto-deleted and the session files plus backups always remain in place.
|
|
191
|
+
- **Capability report**: `mover.status` now enumerates which official services it actually detected (registry, persistence, projection read/write, archive channel, coordinator states, file references, agents) plus degraded features, so support questions answer themselves.
|
|
192
|
+
- Input caps: session / workspace ids are validated (non-empty, ≤ 300 chars) at every entry point; data-cleanup day ranges clamp to [1, 3650].
|
|
193
|
+
|
|
194
|
+
### Fixed
|
|
195
|
+
|
|
196
|
+
- **Backup now precedes every side effect.** `moveSession` previously detached accounting before taking the byte-level backup, so a backup failure left a detached, unaccounted session behind. The pipeline now reads the source and stashes the backup first — a backup failure aborts with `backup-failed` and nothing has been touched (no accounting, no files, no indexes).
|
|
197
|
+
- **Scan truncation kept the wrong 400.** The 400-item scan cap was applied before the mtime sort, so very large libraries showed the oldest directory-order slice while the newest sessions could vanish from the rescue panel entirely. Metadata (stat) is now collected for everything first, sorted newest-first, and only the newest 400 get header-parsed — same parse cost, correct survivors.
|
|
198
|
+
- Tests 70 → 77 (backup-failure zero side effects, concurrent same-session double move → one ok / one busy, repoint-holds-lock → move busy, error-code assertions for conflict / not-writable / unsupported / not-found / invalid-input, newest-400 scan truncation, recovery-record write + recoveryCount).
|
|
199
|
+
|
|
200
|
+
## [1.3.0] - 2026-09-05
|
|
201
|
+
|
|
202
|
+
### Added
|
|
203
|
+
|
|
204
|
+
- **Data protection summary and time-based cleanup**: one combined line over the recycle bin and backups (item counts and footprint), plus a clean-older-than-30-days action — dry-run first (shows exactly how many entries and how much space would be freed), explicit confirmation, then per-item cleanup with the freed-space report. Corrupt or stale entries never block the rest.
|
|
205
|
+
- New RPC endpoint: `mover.data.cleanup` (with `dryRun`).
|
|
206
|
+
- Tests 69 → 70.
|
|
207
|
+
|
|
208
|
+
## [1.2.0] - 2026-09-05
|
|
209
|
+
|
|
210
|
+
### Added
|
|
211
|
+
|
|
212
|
+
- **Migration task center (record-style)**: every bulk move is persisted as a task — per-session state (done / failed with last error and last attempt time), source and target paths. Failed items retry in one click; each retry resolves the session's CURRENT location (never the stale recorded path), stays individually isolated, and an "already at target" failure converges to done (idempotent). Retried moves land in the move history like normal batches, so undo still works. Records are clearable without touching moved sessions.
|
|
213
|
+
- New RPC endpoints: `mover.tasks.list / retry / forget`. `mover.moveMany` results now include a `taskId`.
|
|
214
|
+
- Tests 66 → 69.
|
|
215
|
+
|
|
216
|
+
## [1.1.0] - 2026-09-05
|
|
217
|
+
|
|
218
|
+
### Added
|
|
219
|
+
|
|
220
|
+
- **Preflight completion**: moveSession preflights before touching anything — double-accounting detection (extra owners detached during the move instead of lingering as ghosts), target writability probe, advisory disk-space check. The move detaches ALL owners and the post-move single-owner pass detaches any stale remainder; rollbacks re-attach every prior owner. Results carry a `warnings` array.
|
|
221
|
+
- Tests 64 → 66.
|
|
222
|
+
|
|
223
|
+
## [1.0.0] - 2026-09-05
|
|
224
|
+
|
|
225
|
+
### Added
|
|
226
|
+
|
|
227
|
+
- **Post-move consistency verification**: every relocation — single move, batch move, and workspace re-point — now reads the relocated archive back and requires both the session id and the rewritten cwd to match before the move counts as done; a mismatch rolls the whole move back (destination moved back, original bytes restored) exactly like any other failure. `mover.move` results carry a `verified` flag.
|
|
228
|
+
- **One-click repair**: a "Fix all" action in the rescue panel runs one scan pass and automatically fixes everything fixable — misfiled sessions are homed, unregistered sessions with a matching group are attached — while anything needing a decision (orphans, damaged archives, no matching group) is skipped with a stated reason. Results report fixed / skipped / failed counts; every fix stays individually isolated and goes through the same accounting-only paths (no files are moved).
|
|
229
|
+
- **Panel filter**: a filter box matches title, session id, path, and group across every rescue list — orphaned, unregistered, misfiled, archived, recycle bin, and backups — with per-section shown/total counts; "Home all" acts on the currently filtered set.
|
|
230
|
+
- New RPC endpoint `mover.repairAll`; `verifyRelocatedArtifact` is exported for tooling.
|
|
231
|
+
- Tests 58 → 62 (verification helper pass/mismatch cases, verified flag on moves, repair-all mixed/empty scenarios).
|
|
232
|
+
|
|
233
|
+
## [0.9.0] - 2026-09-05
|
|
234
|
+
|
|
235
|
+
### Added
|
|
236
|
+
|
|
237
|
+
- **Session recycle bin**: the rescue panel's orphaned / unregistered / misfiled / archived rows gain a "Delete" action that moves the whole session into `$DSH_HOME/workspace-mover/recycle/` behind a manifest recording everything needed to bring it back (title, original path, owning group, archive flag, projection snapshot). Deletion clears all four traces — files, workspace accounting, registry indexes, and the projection-cache entry — so nothing lingers as a ghost or stale row. The physical move happens first: a failed delete (or a failed manifest write) rolls everything back and changes nothing. Sessions still resident in harness memory are refused with a clear message (their live objects would zombie-recreate files).
|
|
238
|
+
- **Restore from the recycle bin**: one click back to the original path (re-attaching accounting, re-writing the projection title, and re-entering the archived set when the session was archived), or into any other group — which routes through the full moveSession pipeline (backup, header rewrite, hot fixes, move history). If the original spot is occupied or its workspace is gone, the restore dialog opens with a target picker.
|
|
239
|
+
- **Purge**: single item or empty-the-bin, each behind an explicit confirmation.
|
|
240
|
+
- **Backup management**: every move already kept rolling byte-level backups; they are now visible — grouped per session with copy count, total size, and date span, plus the overall footprint — with one-click restore (to the backup's original location or into any group, header round-trip verified before accounting) and per-session backup deletion.
|
|
241
|
+
- New RPC endpoints: `mover.session.delete`, `mover.trash.list / restore / purge`, `mover.backups.list / restore / deleteOne`. Projection-cache operations degrade gracefully on hosts without the service (stale entries are harmless by design); archive-set changes skip with a warning when the registry lacks the durable state channel.
|
|
242
|
+
- Tests 47 → 58 (delete four-way cleanup, resident refusal, archived delete/restore symmetry, restore to original path / other group / missing workspace, purge, backup aggregation, restore with round-trip verification, per-session backup deletion).
|
|
243
|
+
|
|
244
|
+
## [0.8.1] - 2026-09-05
|
|
245
|
+
|
|
246
|
+
### Fixed
|
|
247
|
+
|
|
248
|
+
- **Directory relocation is now safe on the copy fallback.** `moveDir` previously copied the session directory file-by-file; a mid-copy failure left a partial destination directory behind, and since neither the move nor the workspace re-point wizard cleans up the target on failure, every subsequent retry was rejected with "destination artifact already exists" until files were deleted by hand — with the half-written files (already carrying the new cwd header) polluting scan results. The fallback now uses recursive `cpSync`, cleans up a half-built destination it created on failure (retry is idempotent), and refuses — without touching either side — when the destination directory already exists non-empty (unknown content is never overwritten; the error message explains that a process-interrupt leftover contains only this session's own files and can be removed by hand).
|
|
249
|
+
- Backup pruning matched files with `startsWith(id)`; tightened to `startsWith(id + '.')` so sessions with prefix-adjacent ids (e.g. `session-x` vs `session-x-1`) can never prune each other's backups. Same-millisecond backups of one session overwrite atomically (last-wins) without breaking the retention count.
|
|
250
|
+
- Tests 41 → 47 (recursive relocation, non-empty-destination refusal with both sides untouched, injected copy-failure cleanup, rename-EEXIST fallback, flow-level residual-destination recovery through `mover.move`, backup prefix isolation and same-millisecond retention).
|
|
251
|
+
|
|
252
|
+
## [0.8.0] - 2026-09-05
|
|
253
|
+
|
|
254
|
+
### Added
|
|
255
|
+
|
|
256
|
+
- **Archived session management**: the rescue panel gains an "Archived sessions" block. Sessions hidden by the official archive action — previously unreachable from any UI — are listed under their owning group (the archive set never touches workspace accounting, so ownership survives). One click restores a session to its original group, or "Restore to…" moves it into another group through the same protected move pipeline (backup, history, undo). Sessions whose real folder matches a different workspace carry a homing suggestion, so restoring and re-homing is one decision.
|
|
257
|
+
- **Empty group detection and cleanup**: the rescue panel lists workspaces with zero members — counted against the raw registry ledger (`record.sessionIds`), so archived and ghost roster entries always count as members and never misreport. Single delete or delete-all; each delete re-checks the raw ledger right before acting, and goes through the official workspace delete API (registration only, no session files touched).
|
|
258
|
+
- **"Open folder" in the workspace "…" menu**: opens the group's directory in the system file manager (explorer.exe / open / xdg-open). The RPC only accepts paths belonging to registered workspaces, and refuses missing directories.
|
|
259
|
+
- `mover.archived`, `mover.unarchive`, `mover.openFolder` RPC endpoints; `mover.workspaces` items now carry `rawSessionCount` (raw ledger length, including archived/ghost members, alongside the index-filtered `sessionIds`). Unarchive writes through the registry's durable state channel — the same `enqueueOperation` + `setState` path the official `archiveSession` uses — so changes survive restarts; hosts without that channel fail with a clear "unsupported on this DSH version" error.
|
|
260
|
+
- Tests 35 → 41 cases (archived listing + homing suggestion, unarchive with/without a target including undo round-trip, raw ledger counting, open-folder path validation and per-platform command assembly).
|
|
261
|
+
|
|
262
|
+
### Fixed
|
|
263
|
+
|
|
264
|
+
- The group-merge "deleted empty group" toast never fired: the official `workspaces.delete()` resolves with no value on success (it rejects on failure), so checking `result.ok` mislabeled every successful delete as a failure. The new empty-group cleanup uses the same corrected semantics.
|
|
265
|
+
- Sidebar-visible titles (official auto-naming and renames) live in the projection cache, not in the on-disk session header — so auto-titled sessions showed as "Untitled session" in the archived block and scan lists. Titles now prefer the projection cache (`storages/session_projcache.json`, read-only defensive parse) and fall back to the header.
|
|
266
|
+
- "Open folder" on Windows: the window opens via explorer.exe, and ~0.8s later the plugin attempts to bring it to the front via `WScript.Shell.AppActivate` on the folder title. The attempt can still be denied by Windows' foreground-lock policy depending on what has focus at the moment — the window always opens, but may occasionally need a taskbar click. (Direct explorer spawn alone always opened behind; ShellExecute-based alternatives from the harness host silently do nothing at all.)
|
|
267
|
+
- A session whose group was deleted ("ungrouped" with no path-matching workspace) used to offer only a permanently disabled button; it now gets the same move-into-any-group dropdown as orphaned sessions.
|
|
268
|
+
|
|
269
|
+
## [0.7.0] - 2026-08-28
|
|
270
|
+
|
|
271
|
+
### Added
|
|
272
|
+
|
|
273
|
+
- Misfiled-session detection and one-click homing: the scan now recognizes sessions whose header cwd matches an existing workspace but whose bookkeeping lives elsewhere (clone-style movers, groups recreated after folder renames, double-accounting). The rescue panel lists each as "current group → correct group" with a "Home" button plus a "Home all" batch; homing detaches every wrong owner and attaches the matching workspace without touching files on disk.
|
|
274
|
+
- Group merge: the workspace header's "…" menu gains a "Move whole group…" entry (injected into the official menu; the right-click interception is gone). After the move, an emptied source group can be deleted in one confirmation through the official workspace delete API.
|
|
275
|
+
- `mover.repair` gains the `home` action kind; `mover.scan` items now carry `homeWorkspaceId` / `homeTitle` / `homePath` / `ownerWorkspaceIds` and a `misfiled` status with matching counts.
|
|
276
|
+
- Tests 32 → 35 cases.
|
|
277
|
+
|
|
278
|
+
## [0.6.3] - 2026-08-28
|
|
279
|
+
|
|
280
|
+
### Fixed
|
|
281
|
+
|
|
282
|
+
- **Critical**: multi-select drag could move a session the user never picked. Row-to-id resolution previously aligned visible rows against `workspace.sessionIds` by order; hidden blank/archived members occupy slots without rows, shifting every subsequent pairing. Ids now come from the row's own React props (`SessionNodeItem` `node.id` — the same value the official dragstart writes into the drag payload), with the alignment kept only as a fallback.
|
|
283
|
+
- The "Recently updated" re-sort after moves never executed in the field: the v0.6.1 fiber walk found nothing and v0.6.2 called `workspaces.list()`, which does not exist on the client-side service. Membership is now derived from the order account itself plus the moved session ids, and the exact recency order is written through the official store action — verified end-to-end through the real drop pipeline.
|
|
284
|
+
|
|
285
|
+
## [0.6.2] - 2026-08-28
|
|
286
|
+
|
|
287
|
+
### Fixed
|
|
288
|
+
|
|
289
|
+
- "Recently updated" re-sort after moves is now applied through the official slot system's store instance (`ctx.slots.resolveStore` on the `sidebar.workspaces` registration) instead of walking React fibers, which silently failed in the field. When the account's timestamp cache covers every member, the plugin writes the exact correct recency order itself (replicating the official comparator); otherwise it clears the account so the official reconciliation performs a full re-sort. Flat mode and manual sort are never touched.
|
|
290
|
+
- Undoing a move from the settings panel now re-fetches the workspace baseline, so the session returns to its original group immediately instead of landing in "Ungrouped" until a page refresh (also applied to relink and attach).
|
|
291
|
+
- Starting a multi-select with Ctrl+click now automatically includes the currently open session (the one row the sidebar marks with `aria-selected`), so "open A, Ctrl+click B" selects both in one step.
|
|
292
|
+
|
|
293
|
+
## [0.6.1] - 2026-08-28
|
|
294
|
+
|
|
295
|
+
### Fixed
|
|
296
|
+
|
|
297
|
+
- Bulk moves now aggregate into a single "Recent moves" entry (with per-session sources recorded inside), and one Undo sends every session back to its own original group; sessions whose source workspace disappeared stay in the entry for a retry.
|
|
298
|
+
- Picking a session with a plain click now leaves multi-select automatically — no more stale "N sessions picked" badge after navigating away.
|
|
299
|
+
- Esc clears the multi-select even when the chat input has focus.
|
|
300
|
+
- The sidebar's "Recently updated" sort no longer pins freshly moved sessions to the top: the official per-workspace order account treats any unknown session as newly active and remembers the wrong order. After every move (single, batch, whole-group) and every undo, the plugin clears that workspace's account through the official store action, triggering the same full recency re-sort as manually toggling the sort option — silently, and only while "Recently updated" is the active sort (manual custom order is never touched).
|
|
301
|
+
|
|
302
|
+
## [0.6.0] - 2026-08-28
|
|
303
|
+
|
|
304
|
+
### Added
|
|
305
|
+
|
|
306
|
+
- Bulk move via multi-select drag: Ctrl/Cmd+click toggles sidebar rows, Shift+click extends within a group, Esc clears; dragging any picked row moves the whole set. Selection is built by the plugin (the sidebar has no native multi-select) with a live count badge.
|
|
307
|
+
- Move a whole group: the workspace header's "…" menu picks a target group and bulk-moves its accounted sessions. (Later versions moved this entry off the right-click menu to avoid clashing with the official menu.)
|
|
308
|
+
- New RPC endpoint `mover.moveMany`: up to 50 sessions per batch, reusing the single-move pipeline — independent per-session backup/rollback, per-item error isolation, and per-move history entries (batch results stay undoable one by one).
|
|
309
|
+
- Row-to-session resolution aligns each group's DOM rows with `workspace.sessionIds` order and disambiguates via `mover.scan` titles, so officially hidden blank sessions cannot shift the mapping.
|
|
310
|
+
|
|
311
|
+
## [0.5.1] - 2026-08-27
|
|
312
|
+
|
|
313
|
+
### Fixed
|
|
314
|
+
|
|
315
|
+
- Workspace titles now follow folder renames during move-home when the title still equals the old folder's basename (the official `create` default); user-chosen titles are preserved.
|
|
316
|
+
- Resident sessions get their frozen in-memory header swapped to the new cwd after a move, so `@` file references rebuild their search root without a harness restart.
|
|
317
|
+
- Stale `@` file-reference search caches rooted at the old path are disposed after every move/repoint.
|
|
318
|
+
- Projection-cache checkpoints have their log identity (`identity.cwd`) aligned after header rewrites, so cold starts keep serving cached projections (session titles) instead of discarding them and lazily falling back to the group name until first open.
|
|
319
|
+
|
|
320
|
+
## [0.5.0] - 2026-08-27
|
|
321
|
+
|
|
322
|
+
### Added
|
|
323
|
+
|
|
324
|
+
- Workspace health panel: settings view lists every workspace with its official status (`ok` / `missing-dir`) and raw membership count.
|
|
325
|
+
- Move-home wizard: redirects a stale workspace in place through the entity's unified `mutate` channel (workspace id, title, order and archive flags preserved), after pre-seeding registry indexes so the membership prune keeps everyone.
|
|
326
|
+
- Batch migration of all affected sessions — accounted members plus stranded orphans still on the old path — with per-file backup, automatic rollback and resident-session write-state cleanup.
|
|
327
|
+
- Resume support: rerun the same wizard inputs and only the remaining stragglers are processed; running sessions are skipped per-file, never pruned.
|
|
328
|
+
- New RPC endpoints: `mover.ws.audit`, `mover.repoint`.
|
|
329
|
+
|
|
330
|
+
### Fixed
|
|
331
|
+
|
|
332
|
+
- Ghost detection now iterates raw `record.sessionIds`; the official filtered getter hides exactly the missing-on-disk entries ghosts are.
|
|
333
|
+
|
|
334
|
+
## [0.4.0] - 2026-08-26
|
|
335
|
+
|
|
336
|
+
### Added
|
|
337
|
+
|
|
338
|
+
- Display session titles in move confirmations, repair lists, and recent move history.
|
|
339
|
+
- Persist the latest 100 cross-workspace moves.
|
|
340
|
+
- Add `mover.history` and `mover.undo` RPC endpoints.
|
|
341
|
+
- Add one-click undo in Settings > Session Repair.
|
|
342
|
+
|
|
343
|
+
## [0.3.2]
|
|
344
|
+
|
|
345
|
+
- Added session scanning, orphan repair, unregistered-session attachment, and rollback protection.
|