dsh-claude-move 0.4.4 → 0.4.6
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 +29 -0
- package/README.es.md +7 -6
- package/README.hi.md +7 -6
- package/README.md +7 -6
- package/README.pt.md +7 -6
- package/README.zh.md +7 -6
- package/index.mjs +42 -27
- package/package.json +18 -20
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,35 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project are documented here. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions follow [SemVer](https://semver.org/).
|
|
4
4
|
|
|
5
|
+
## [Unreleased]
|
|
6
|
+
|
|
7
|
+
## [0.4.6] - 2026-09-10
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- Pin the `@deepseek-ai/dsh-*` dev/test dependencies to the published `0.1.5-rc.1` line and record `0.1.5-rc.1` in `dshWorkshop.compatibility.dshVersions`; the monthly Compat workflow now runs against `0.1.5-rc.1`. The peer range `>=0.1.2-rc.1 <0.2.0 || >=0.1.5-alpha.1 <0.2.0` is unchanged, so no supported host line is dropped.
|
|
12
|
+
|
|
13
|
+
### Docs
|
|
14
|
+
|
|
15
|
+
- Refresh the five-language README compatibility baseline to `dsh-v0.1.5-rc.1` (verified 2026-09-10).
|
|
16
|
+
|
|
17
|
+
## [0.4.5] - 2026-09-09
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- Handle-baseline imports are resumable again on dsh 0.1.3+/0.1.5: synthesized `assistant/message` events now carry `stream: []` whenever the backend's current session format version is >= 2 (feature-gated on the backend-declared version, never guessed). Session format V3's restore boundary (`assertAssistantSettlementShape`) asserts `Array.isArray(data.stream)` and rejected the previous payload with `seed assistant/message at index N has invalid settlement fields` — the log was written and read back fine, but `resume`/fork/seed-session paths failed loudly, so imported sessions could not be continued. The legacy path (<=0.1.2-rc.1) keeps its exact 0.3.x payload with no `stream` (the frozen v0/v1 dispositions reject the field), and handle backends reporting format < 2 are left untouched.
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- Raise the adaptation baseline to `dsh 0.1.5-alpha.1` (session format V3): the 15 `@deepseek-ai/dsh-*` devDependency pins move from `0.1.2-rc.1` to `0.1.5-alpha.1`, the `@deepseek-ai/dsh-tools` peer range becomes `>=0.1.2-rc.1 <0.2.0 || >=0.1.5-alpha.1 <0.2.0` (the single old band cannot match both lines under prerelease resolution), and `dshWorkshop.compatibility.dshVersions` lists both `0.1.2-rc.1` and `0.1.5-alpha.1`.
|
|
26
|
+
- `compat.yml` now exercises the handle persistence seam in CI: the stale "handle seam is unreleased, checkout-only" note is replaced by a two-baseline note, and a new `profile-alpha` job installs `@deepseek-ai/dsh@0.1.5-alpha.1` + `dsh-base`/`dsh-headless` + the packed tarball (row mount, keyless smoke, uninstall). The existing `0.1.2-rc.1` profile job stays as the legacy-line regression.
|
|
27
|
+
|
|
28
|
+
### Docs
|
|
29
|
+
|
|
30
|
+
- Correct the "the handle seam is unreleased" claim in `AGENTS.md`, `ARCHITECTURE.md` (decisions 14/15 and the verification section), the five READMEs, `PLAN.md` and the compat workflow: `@deepseek-ai/dsh-session-persistence` / `-jsonl` publish the handle API on the `0.1.5-alpha.1` alpha line, so the handle path is CI-verifiable instead of checkout-only. This supersedes the "unreleased checkout handle seam" wording kept in the historical 0.4.0 entry above.
|
|
31
|
+
- Five-language READMEs: the compatibility section now states the verified host `dsh-v0.1.5-alpha.1` (2026-09-09), the dual peer range, the `0.1.5-alpha.1` devDependency pins and the one-way V3 log direction (logs written here cannot be read by `dsh <= 0.1.2-rc.1`; re-import from the source transcript is the fallback).
|
|
32
|
+
- Add an L6 compatibility suite (`test/compat-v3.test.mjs`) that runs the real host `Session.fromRestore` on imported logs: a new handle-path log resumes, the pre-fix shape (no `stream`) is rejected with the exact settlement error, a legacy-path log keeps its v0 shape and still exports, and format < 2 backends receive no `stream`. Sync the fixtures/assertions in the handle, import, export and convert suites (241 tests).
|
|
33
|
+
|
|
5
34
|
## [0.4.4] - 2026-09-08
|
|
6
35
|
|
|
7
36
|
### Docs
|
package/README.es.md
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
[](LICENSE)
|
|
11
11
|
[](https://github.com/topics/dsh-plugin)
|
|
12
|
+
[](https://github.com/PerryLink/dsh-plugin-doctor#verified-徽章)
|
|
12
13
|
[](#)
|
|
13
14
|
[](https://github.com/PerryLink/dsh-claude-move/actions)
|
|
14
15
|
[](https://github.com/PerryLink/dsh-claude-move/releases)
|
|
@@ -23,10 +24,10 @@
|
|
|
23
24
|
|
|
24
25
|
## Compatibilidad
|
|
25
26
|
|
|
26
|
-
- Dirigido a `dsh 0.1.
|
|
27
|
-
`0.1.2-rc.1` (adaptado el 2026-09-04): el sobre de sesión conserva su campo ignorable solo para compatibilidad de lectura de logs almacenados - Session.append aún no puede estamparlo, por lo que el comportamiento de la puerta no cambia.
|
|
28
|
-
- 0.4.0 incluye un shim de doble línea base para `sessionPersistence` en tiempo de ejecución, detectado por la forma de la API (nunca por versión): funcionan tanto la API heredada
|
|
29
|
-
- Última verificación con una instalación nueva desde tarball: escaneo real, importación por lotes real (reimportación idempotente), adjuntado al workspace y artefactos de persistencia confirmados; macOS/Linux cubiertos por la matriz de CI.
|
|
27
|
+
- Dirigido a `dsh 0.1.5-rc.1` (perfil web, formato de sesión V3); las dependencias peer requieren `>=0.1.2-rc.1 <0.2.0 || >=0.1.5-alpha.1 <0.2.0`. Verificado contra `dsh-v0.1.5-rc.1` el 2026-09-10. Node `^22.19 || >=24`.
|
|
28
|
+
`0.1.2-rc.1` (adaptado el 2026-09-04): el sobre de sesión conserva su campo ignorable solo para compatibilidad de lectura de logs almacenados - Session.append aún no puede estamparlo, por lo que el comportamiento de la puerta no cambia.
|
|
29
|
+
- 0.4.0 incluye un shim de doble línea base para `sessionPersistence` en tiempo de ejecución, detectado por la forma de la API (nunca por versión): funcionan tanto la API heredada (`create`/`append`/`readFrom`, `list()` devolviendo cabeceras) como la costura de handle (`create` devolviendo un `SessionHandle`, `list()`/`stat()` devolviendo instantáneas). La costura de handle ya está publicada en la línea alpha (`@deepseek-ai/dsh-session-persistence` / `-jsonl` `0.1.5-rc.1`), así que el workflow de compatibilidad la cubre. En la ruta handle, cada append va seguido de `flush()` (barrera de durabilidad) y un `close()` emparejado (propiedad de escritor único); las cabeceras se sellan con la versión de formato actual del backend y un `isSeeded` explícito; las fuentes de modelo de asistente ausentes caen al provider; y desde 0.4.5 los eventos `assistant/message` sintetizados llevan `stream: []` cuando la versión de formato del backend es >= 2 — `Session.fromRestore` de V3 exige `Array.isArray(data.stream)`, así que sin él el log se escribía y se leía pero no se podía reanudar. La limpieza del escaneo de importación se niega a ejecutarse cuando el `header.id` de un elemento listado no se puede resolver, por lo que `imports.json` nunca se vacía en silencio.
|
|
30
|
+
- Última verificación con una instalación nueva desde tarball: escaneo real, importación por lotes real (reimportación idempotente), adjuntado al workspace y artefactos de persistencia confirmados; macOS/Linux cubiertos por la matriz de CI. Los logs importados usan el formato de sesión V3 y `dsh <= 0.1.2-rc.1` no puede leerlos (la actualización es unidireccional; la alternativa es reimportar desde el transcript de origen).
|
|
30
31
|
|
|
31
32
|
### Matriz de compatibilidad (solo costuras públicas)
|
|
32
33
|
|
|
@@ -36,7 +37,7 @@
|
|
|
36
37
|
| `sessionPersistence` doble línea base: heredada `listSnapshots` / `readFrom` / `append` frente a handle `open` / `stat` / `list()` de instantáneas | detectado por característica en tiempo de ejecución (forma de API, nunca versión) | la guarda de resolución de `header.id` aborta el escaneo en voz alta en vez de vaciar `imports.json` en silencio |
|
|
37
38
|
| `fs` con capacidad `streamText` / `ctx.jobs` / `ctx.agents.resume` | detectado por característica | lectura de archivo completo con rechazo en voz alta / mapa de jobs propio / inyección de traspaso |
|
|
38
39
|
| Servicios de shell del cliente (`sessions.refresh/open`, `workspaces.refresh`) | detectado por característica al aplicar el panel | recarga completa de la página |
|
|
39
|
-
| Las capacidades de plataforma más nuevas nunca son requisitos estrictos — el plugin sigue arrancando en rc.
|
|
40
|
+
| Las capacidades de plataforma más nuevas nunca son requisitos estrictos — el plugin sigue arrancando en la línea más antigua soportada (`0.1.2-rc.1`). | | |
|
|
40
41
|
|
|
41
42
|
## Qué obtienes
|
|
42
43
|
|
|
@@ -255,7 +256,7 @@ Este proyecto está licenciado bajo la Apache License 2.0; los siguientes compon
|
|
|
255
256
|
## Desarrollo
|
|
256
257
|
|
|
257
258
|
```sh
|
|
258
|
-
npm install # peer deps: @deepseek-ai/dsh-tools@>=0.1.2-rc.1, @deepseek-ai/cordis, schemastery
|
|
259
|
+
npm install # peer deps: @deepseek-ai/dsh-tools@>=0.1.2-rc.1 <0.2.0 || >=0.1.5-alpha.1 <0.2.0, @deepseek-ai/cordis, schemastery
|
|
259
260
|
npm test # node --test test/*.test.mjs
|
|
260
261
|
```
|
|
261
262
|
|
package/README.hi.md
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
[](LICENSE)
|
|
11
11
|
[](https://github.com/topics/dsh-plugin)
|
|
12
|
+
[](https://github.com/PerryLink/dsh-plugin-doctor#verified-徽章)
|
|
12
13
|
[](#)
|
|
13
14
|
[](https://github.com/PerryLink/dsh-claude-move/actions)
|
|
14
15
|
[](https://github.com/PerryLink/dsh-claude-move/releases)
|
|
@@ -23,10 +24,10 @@
|
|
|
23
24
|
|
|
24
25
|
## अनुकूलता
|
|
25
26
|
|
|
26
|
-
- `dsh 0.1.
|
|
27
|
-
`0.1.2-rc.1` (2026-09-04 को अनुकूलित): सत्र लिफ़ाफ़ा अपना ignorable फ़ील्ड केवल संग्रहीत-लॉग पठन संगतता के लिए रखता है - Session.append अभी भी इसे स्टैम्प नहीं कर सकता, इसलिए गेट व्यवहार अपरिवर्तित है।
|
|
28
|
-
- 0.4.0 में `sessionPersistence` के लिए दोहरी-बेसलाइन रनटाइम shim शामिल है, जिसे API आकार से पहचाना जाता है (संस्करण से कभी नहीं):
|
|
29
|
-
- अंतिम बार एक ताज़ा tarball इंस्टॉल के विरुद्ध सत्यापित: वास्तविक स्कैन, वास्तविक बैच आयात (आइडेम्पोटेंट पुनः-आयात), workspace जुड़ाव और पर्सिस्टेंस आर्टिफैक्ट की पुष्टि; macOS/Linux CI मैट्रिक्स द्वारा कवर हैं।
|
|
27
|
+
- `dsh 0.1.5-rc.1` (web profile, सत्र प्रारूप V3) को लक्षित करता है; peer निर्भरताएँ `>=0.1.2-rc.1 <0.2.0 || >=0.1.5-alpha.1 <0.2.0` चाहिए। 2026-09-10 को `dsh-v0.1.5-rc.1` के विरुद्ध सत्यापित। Node `^22.19 || >=24`।
|
|
28
|
+
`0.1.2-rc.1` (2026-09-04 को अनुकूलित): सत्र लिफ़ाफ़ा अपना ignorable फ़ील्ड केवल संग्रहीत-लॉग पठन संगतता के लिए रखता है - Session.append अभी भी इसे स्टैम्प नहीं कर सकता, इसलिए गेट व्यवहार अपरिवर्तित है।
|
|
29
|
+
- 0.4.0 में `sessionPersistence` के लिए दोहरी-बेसलाइन रनटाइम shim शामिल है, जिसे API आकार से पहचाना जाता है (संस्करण से कभी नहीं): लीगेसी API (`create`/`append`/`readFrom`, `list()` हेडर लौटाता है) और हैंडल सीम (`create` एक `SessionHandle` लौटाता है, `list()`/`stat()` स्नैपशॉट लौटाते हैं) दोनों काम करते हैं। हैंडल सीम अब alpha लाइन पर प्रकाशित है (`@deepseek-ai/dsh-session-persistence` / `-jsonl` `0.1.5-rc.1`), इसलिए compat वर्कफ़्लो उसे कवर करता है। हैंडल पथ पर हर append के बाद `flush()` (स्थायित्व अवरोध) और युग्मित `close()` (एकल-लेखक स्वामित्व) होता है; हेडर पर बैकएंड का वर्तमान प्रारूप संस्करण और स्पष्ट `isSeeded` अंकित होता है; अनुपस्थित assistant model स्रोत provider पर गिरते हैं; और 0.4.5 से संश्लेषित `assistant/message` ईवेंट तब `stream: []` लेकर आते हैं जब बैकएंड प्रारूप संस्करण >= 2 हो — V3 का `Session.fromRestore` `Array.isArray(data.stream)` माँगता है, इसलिए उसके बिना लॉग लिखा और पढ़ा तो जाता था पर फिर से शुरू नहीं हो सकता था। जब किसी सूचीबद्ध तत्व का `header.id` हल नहीं हो पाता तो आयात-स्कैन की सफ़ाई चलने से मना कर देती है, इसलिए `imports.json` कभी चुपचाप खाली नहीं होता।
|
|
30
|
+
- अंतिम बार एक ताज़ा tarball इंस्टॉल के विरुद्ध सत्यापित: वास्तविक स्कैन, वास्तविक बैच आयात (आइडेम्पोटेंट पुनः-आयात), workspace जुड़ाव और पर्सिस्टेंस आर्टिफैक्ट की पुष्टि; macOS/Linux CI मैट्रिक्स द्वारा कवर हैं। आयातित लॉग सत्र प्रारूप V3 में हैं और `dsh <= 0.1.2-rc.1` उन्हें पढ़ नहीं सकता (उन्नयन एकतरफ़ा है; विकल्प स्रोत transcript से पुनः आयात है)।
|
|
30
31
|
|
|
31
32
|
### अनुकूलता मैट्रिक्स (केवल सार्वजनिक सीम)
|
|
32
33
|
|
|
@@ -36,7 +37,7 @@
|
|
|
36
37
|
| `sessionPersistence` दोहरी बेसलाइन: लीगेसी `listSnapshots` / `readFrom` / `append` बनाम हैंडल `open` / `stat` / स्नैपशॉट `list()` | रनटाइम पर फ़ीचर-डिटेक्टेड (API आकार, संस्करण कभी नहीं) | `header.id` रिज़ॉल्यूशन गार्ड स्कैन को ज़ोर से रोक देता है, `imports.json` चुपचाप खाली करने के बजाय |
|
|
37
38
|
| `streamText`-सक्षम `fs` / `ctx.jobs` / `ctx.agents.resume` | फ़ीचर-डिटेक्टेड | पूरी फ़ाइल पढ़ना और ज़ोर से अस्वीकार / स्वयं का job map / हैंडऑफ़ इंजेक्ट |
|
|
38
39
|
| Client shell सेवाएँ (`sessions.refresh/open`, `workspaces.refresh`) | पैनल apply पर फ़ीचर-डिटेक्टेड | पूर्ण-पृष्ठ रीलोड |
|
|
39
|
-
| नई प्लेटफ़ॉर्म क्षमताएँ कभी कठोर आवश्यकताएँ नहीं होतीं — प्लगइन rc.
|
|
40
|
+
| नई प्लेटफ़ॉर्म क्षमताएँ कभी कठोर आवश्यकताएँ नहीं होतीं — प्लगइन सबसे पुरानी समर्थित लाइन (`0.1.2-rc.1`) पर बूट होने योग्य रहता है। | | |
|
|
40
41
|
|
|
41
42
|
## आपको क्या मिलता है
|
|
42
43
|
|
|
@@ -255,7 +256,7 @@ claude_export { sessionId: "...", path: "~/.claude/projects/<slug>/<id>.jsonl" }
|
|
|
255
256
|
## विकास
|
|
256
257
|
|
|
257
258
|
```sh
|
|
258
|
-
npm install # peer deps: @deepseek-ai/dsh-tools@>=0.1.2-rc.1, @deepseek-ai/cordis, schemastery
|
|
259
|
+
npm install # peer deps: @deepseek-ai/dsh-tools@>=0.1.2-rc.1 <0.2.0 || >=0.1.5-alpha.1 <0.2.0, @deepseek-ai/cordis, schemastery
|
|
259
260
|
npm test # node --test test/*.test.mjs
|
|
260
261
|
```
|
|
261
262
|
|
package/README.md
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
[](LICENSE)
|
|
12
12
|
[](https://github.com/topics/dsh-plugin)
|
|
13
|
+
[](https://github.com/PerryLink/dsh-plugin-doctor#verified-徽章)
|
|
13
14
|
[](#)
|
|
14
15
|
[](https://github.com/PerryLink/dsh-claude-move/actions)
|
|
15
16
|
[](https://github.com/PerryLink/dsh-claude-move/releases)
|
|
@@ -24,10 +25,10 @@
|
|
|
24
25
|
|
|
25
26
|
## Compatibility
|
|
26
27
|
|
|
27
|
-
- Targets `dsh 0.1.
|
|
28
|
-
`0.1.2-rc.1` (adapted 2026-09-04): the session envelope keeps its ignorable field for stored-log read compatibility only - Session.append still cannot stamp it, so audit-gate behavior is unchanged.
|
|
29
|
-
- 0.4.0 ships a dual-baseline `sessionPersistence` runtime shim, feature-detected by API shape (never by version): the
|
|
30
|
-
- Last verified against a fresh tarball install: real scan, real batch import (idempotent re-import), workspace attach and persistence artifacts confirmed; macOS/Linux covered by the CI matrix.
|
|
28
|
+
- Targets `dsh 0.1.5-rc.1` (web profile, session format V3); peer dependencies require `>=0.1.2-rc.1 <0.2.0 || >=0.1.5-alpha.1 <0.2.0`. Verified against `dsh-v0.1.5-rc.1` on 2026-09-10. Node `^22.19 || >=24`.
|
|
29
|
+
`0.1.2-rc.1` (adapted 2026-09-04): the session envelope keeps its ignorable field for stored-log read compatibility only - Session.append still cannot stamp it, so audit-gate behavior is unchanged.
|
|
30
|
+
- 0.4.0 ships a dual-baseline `sessionPersistence` runtime shim, feature-detected by API shape (never by version): the legacy API (`create`/`append`/`readFrom`, `list()` returning headers) and the handle seam (`create` returning a `SessionHandle`, `list()`/`stat()` returning snapshots) both work. The handle seam is published on the alpha line (`@deepseek-ai/dsh-session-persistence` / `-jsonl` `0.1.5-rc.1`), so the compat workflow covers it. On the handle path every append is followed by `flush()` (durability barrier) and a paired `close()` (single-writer ownership); headers are stamped with the backend's current format version plus an explicit `isSeeded`; missing assistant model sources fall back to the provider; and since 0.4.5 synthesized `assistant/message` events carry `stream: []` when the backend format version is >= 2 — V3's `Session.fromRestore` asserts `Array.isArray(data.stream)`, so without it a log was written and readable but could not be resumed. Import-scan cleanup refuses to run when a listed element's `header.id` cannot be resolved, so `imports.json` is never silently cleared.
|
|
31
|
+
- Last verified against a fresh tarball install: real scan, real batch import (idempotent re-import), workspace attach and persistence artifacts confirmed; macOS/Linux covered by the CI matrix. Imported logs use session format V3 and cannot be read by `dsh <= 0.1.2-rc.1` (upgrading is one-way; re-import from the source transcript is the fallback).
|
|
31
32
|
|
|
32
33
|
### Compatibility matrix (public seams only)
|
|
33
34
|
|
|
@@ -37,7 +38,7 @@
|
|
|
37
38
|
| `sessionPersistence` dual baseline: legacy `listSnapshots` / `readFrom` / `append` vs handle `open` / `stat` / snapshot `list()` | feature-detected at runtime (API shape, never version) | the `header.id` resolution guard aborts the scan loudly instead of silently clearing `imports.json` |
|
|
38
39
|
| `streamText`-capable `fs` / `ctx.jobs` / `ctx.agents.resume` | feature-detected | whole-file read with loud rejection / own job map / handoff inject |
|
|
39
40
|
| Client shell services (`sessions.refresh/open`, `workspaces.refresh`) | feature-detected at panel apply | full-page reload |
|
|
40
|
-
| Newer platform capabilities are never hard requirements — the plugin stays bootable on rc.
|
|
41
|
+
| Newer platform capabilities are never hard requirements — the plugin stays bootable on the oldest supported line (`0.1.2-rc.1`). | | |
|
|
41
42
|
|
|
42
43
|
## What you get
|
|
43
44
|
|
|
@@ -256,7 +257,7 @@ This project is licensed under the Apache License 2.0; the following MIT-license
|
|
|
256
257
|
## Development
|
|
257
258
|
|
|
258
259
|
```sh
|
|
259
|
-
npm install # peer deps: @deepseek-ai/dsh-tools@>=0.1.2-rc.1, @deepseek-ai/cordis, schemastery
|
|
260
|
+
npm install # peer deps: @deepseek-ai/dsh-tools@>=0.1.2-rc.1 <0.2.0 || >=0.1.5-alpha.1 <0.2.0, @deepseek-ai/cordis, schemastery
|
|
260
261
|
npm test # node --test test/*.test.mjs
|
|
261
262
|
```
|
|
262
263
|
|
package/README.pt.md
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
[](LICENSE)
|
|
11
11
|
[](https://github.com/topics/dsh-plugin)
|
|
12
|
+
[](https://github.com/PerryLink/dsh-plugin-doctor#verified-徽章)
|
|
12
13
|
[](#)
|
|
13
14
|
[](https://github.com/PerryLink/dsh-claude-move/actions)
|
|
14
15
|
[](https://github.com/PerryLink/dsh-claude-move/releases)
|
|
@@ -23,10 +24,10 @@
|
|
|
23
24
|
|
|
24
25
|
## Compatibilidade
|
|
25
26
|
|
|
26
|
-
- Direcionado a `dsh 0.1.
|
|
27
|
-
`0.1.2-rc.1` (adaptado em 2026-09-04): o envelope de sessão mantém seu campo ignorable apenas para compatibilidade de leitura de logs armazenados - o Session.append ainda não consegue estampá-lo, então o comportamento da porta não muda.
|
|
28
|
-
- A 0.4.0 inclui um shim de linha de base dupla para `sessionPersistence` em tempo de execução, detectado pela forma da API (nunca pela versão): funcionam tanto a API legada
|
|
29
|
-
- Última verificação contra uma instalação nova de tarball: varredura real, importação em lote real (reimportação idempotente), anexo ao workspace e artefatos de persistência confirmados; macOS/Linux cobertos pela matriz de CI.
|
|
27
|
+
- Direcionado a `dsh 0.1.5-rc.1` (perfil web, formato de sessão V3); dependências peer exigem `>=0.1.2-rc.1 <0.2.0 || >=0.1.5-alpha.1 <0.2.0`. Verificado contra `dsh-v0.1.5-rc.1` em 2026-09-10. Node `^22.19 || >=24`.
|
|
28
|
+
`0.1.2-rc.1` (adaptado em 2026-09-04): o envelope de sessão mantém seu campo ignorable apenas para compatibilidade de leitura de logs armazenados - o Session.append ainda não consegue estampá-lo, então o comportamento da porta não muda.
|
|
29
|
+
- A 0.4.0 inclui um shim de linha de base dupla para `sessionPersistence` em tempo de execução, detectado pela forma da API (nunca pela versão): funcionam tanto a API legada (`create`/`append`/`readFrom`, `list()` retornando cabeçalhos) quanto a costura de handle (`create` retornando um `SessionHandle`, `list()`/`stat()` retornando snapshots). A costura de handle já está publicada na linha alpha (`@deepseek-ai/dsh-session-persistence` / `-jsonl` `0.1.5-rc.1`), então o fluxo de compatibilidade a cobre. No caminho handle, todo append é seguido de `flush()` (barreira de durabilidade) e um `close()` pareado (propriedade de escritor único); os cabeçalhos são carimbados com a versão de formato atual do backend e um `isSeeded` explícito; fontes de modelo de assistente ausentes caem para o provider; e desde 0.4.5 os eventos `assistant/message` sintetizados carregam `stream: []` quando a versão de formato do backend é >= 2 — o `Session.fromRestore` do V3 exige `Array.isArray(data.stream)`, então sem isso o log era escrito e lido, mas não podia ser retomado. A limpeza da varredura de importação se recusa a executar quando o `header.id` de um elemento listado não pode ser resolvido, então `imports.json` nunca é esvaziado silenciosamente.
|
|
30
|
+
- Última verificação contra uma instalação nova de tarball: varredura real, importação em lote real (reimportação idempotente), anexo ao workspace e artefatos de persistência confirmados; macOS/Linux cobertos pela matriz de CI. Os logs importados usam o formato de sessão V3 e `dsh <= 0.1.2-rc.1` não consegue lê-los (a atualização é unidirecional; a alternativa é reimportar do transcript de origem).
|
|
30
31
|
|
|
31
32
|
### Matriz de compatibilidade (somente costuras públicas)
|
|
32
33
|
|
|
@@ -36,7 +37,7 @@
|
|
|
36
37
|
| `sessionPersistence` linha de base dupla: legada `listSnapshots` / `readFrom` / `append` versus handle `open` / `stat` / `list()` de snapshots | detectado por recurso em tempo de execução (forma da API, nunca versão) | a guarda de resolução de `header.id` aborta a varredura em voz alta em vez de esvaziar `imports.json` silenciosamente |
|
|
37
38
|
| `fs` com capacidade `streamText` / `ctx.jobs` / `ctx.agents.resume` | detectado por recurso | leitura de arquivo inteiro com rejeição em voz alta / mapa de jobs próprio / injeção de handoff |
|
|
38
39
|
| Serviços de shell do cliente (`sessions.refresh/open`, `workspaces.refresh`) | detectado por recurso ao aplicar o painel | recarga completa da página |
|
|
39
|
-
| Capacidades de plataforma mais novas nunca são requisitos rígidos — o plugin continua inicializável
|
|
40
|
+
| Capacidades de plataforma mais novas nunca são requisitos rígidos — o plugin continua inicializável na linha mais antiga suportada (`0.1.2-rc.1`). | | |
|
|
40
41
|
|
|
41
42
|
## O que você recebe
|
|
42
43
|
|
|
@@ -255,7 +256,7 @@ Este projeto está licenciado sob a Apache License 2.0; os seguintes componentes
|
|
|
255
256
|
## Desenvolvimento
|
|
256
257
|
|
|
257
258
|
```sh
|
|
258
|
-
npm install # peer deps: @deepseek-ai/dsh-tools@>=0.1.2-rc.1, @deepseek-ai/cordis, schemastery
|
|
259
|
+
npm install # peer deps: @deepseek-ai/dsh-tools@>=0.1.2-rc.1 <0.2.0 || >=0.1.5-alpha.1 <0.2.0, @deepseek-ai/cordis, schemastery
|
|
259
260
|
npm test # node --test test/*.test.mjs
|
|
260
261
|
```
|
|
261
262
|
|
package/README.zh.md
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
[](LICENSE)
|
|
11
11
|
[](https://github.com/topics/dsh-plugin)
|
|
12
|
+
[](https://github.com/PerryLink/dsh-plugin-doctor#verified-徽章)
|
|
12
13
|
[](#)
|
|
13
14
|
[](https://github.com/PerryLink/dsh-claude-move/actions)
|
|
14
15
|
[](https://github.com/PerryLink/dsh-claude-move/releases)
|
|
@@ -23,10 +24,10 @@
|
|
|
23
24
|
|
|
24
25
|
## 兼容性
|
|
25
26
|
|
|
26
|
-
- 面向 `dsh 0.1.
|
|
27
|
-
`0.1.2-rc.1`(2026-09-04 已适配):会话信封保留 ignorable 字段但仅用于存量日志读取兼容——Session.append 仍无法盖章,门控行为不变。
|
|
28
|
-
- 0.4.0 内置 `sessionPersistence` 双基线运行时 shim,按 API
|
|
29
|
-
- 最近针对全新 tarball 安装验证:真实扫描、真实批量导入(幂等重导入)、工作区挂载与持久化产物均已确认;macOS/Linux 由 CI
|
|
27
|
+
- 面向 `dsh 0.1.5-rc.1`(web profile,会话格式 V3);peer 依赖要求 `>=0.1.2-rc.1 <0.2.0 || >=0.1.5-alpha.1 <0.2.0`。已于 2026-09-10 对照 `dsh-v0.1.5-rc.1` 验证。Node `^22.19 || >=24`。
|
|
28
|
+
`0.1.2-rc.1`(2026-09-04 已适配):会话信封保留 ignorable 字段但仅用于存量日志读取兼容——Session.append 仍无法盖章,门控行为不变。
|
|
29
|
+
- 0.4.0 内置 `sessionPersistence` 双基线运行时 shim,按 API 形状特性探测(绝不按版本号猜测):旧 API(`create`/`append`/`readFrom`,`list()` 返回会话头)与 handle seam(`create` 返回 `SessionHandle`,`list()`/`stat()` 返回快照)都能工作。handle seam 已随 alpha 线发布(`@deepseek-ai/dsh-session-persistence` / `-jsonl` `0.1.5-rc.1`),因此 compat workflow 可以覆盖它。handle 路径上每次 append 之后必须 `flush()`(耐久屏障)并成对 `close()`(单写所有权);header 盖上后端当前格式版本并显式补 `isSeeded`;缺失的 assistant model 来源回退 provider;自 0.4.5 起,后端格式版本 >= 2 时合成的 `assistant/message` 带 `stream: []`——V3 的 `Session.fromRestore` 断言 `Array.isArray(data.stream)`,缺它则日志能写入、能读回却不可续聊。导入扫描的清理在列表元素的 `header.id` 无法解析时拒绝执行,绝不静默清空 `imports.json`。
|
|
30
|
+
- 最近针对全新 tarball 安装验证:真实扫描、真实批量导入(幂等重导入)、工作区挂载与持久化产物均已确认;macOS/Linux 由 CI 矩阵覆盖。导入日志为会话格式 V3,`dsh <= 0.1.2-rc.1` 无法读取(升级是单向的;回退办法是从源 transcript 重新导入)。
|
|
30
31
|
|
|
31
32
|
### 兼容性矩阵(仅公开接缝)
|
|
32
33
|
|
|
@@ -36,7 +37,7 @@
|
|
|
36
37
|
| `sessionPersistence` 双基线:旧 API(`listSnapshots` / `readFrom` / `append`)或 handle(`open` / `stat`、快照 `list()`) | 运行时按 API 形状特性探测 | `header.id` 解析守卫:解析失败大声中止扫描,绝不静默清空 `imports.json` |
|
|
37
38
|
| 支持 `streamText` 的 `fs` / `ctx.jobs` / `ctx.agents.resume` | 特性探测 | 整文件读取并大声拒绝 / 自有 job map / 交接注入 |
|
|
38
39
|
| Client shell 服务(`sessions.refresh/open`、`workspaces.refresh`) | 面板 apply 时特性探测 | 整页刷新 |
|
|
39
|
-
| 较新的平台能力从不是硬性要求 ——
|
|
40
|
+
| 较新的平台能力从不是硬性要求 —— 插件在最早支持线(`0.1.2-rc.1`)上始终保持可启动。 | | |
|
|
40
41
|
|
|
41
42
|
## 你能获得什么
|
|
42
43
|
|
|
@@ -255,7 +256,7 @@ Web 面板:一个浮动迁移面板,包含项目/会话树、状态徽章(
|
|
|
255
256
|
## 开发
|
|
256
257
|
|
|
257
258
|
```sh
|
|
258
|
-
npm install # peer 依赖:@deepseek-ai/dsh-tools@>=0.1.2-rc.1、@deepseek-ai/cordis、schemastery
|
|
259
|
+
npm install # peer 依赖:@deepseek-ai/dsh-tools@>=0.1.2-rc.1 <0.2.0 || >=0.1.5-alpha.1 <0.2.0、@deepseek-ai/cordis、schemastery
|
|
259
260
|
npm test # node --test test/*.test.mjs
|
|
260
261
|
```
|
|
261
262
|
|
package/index.mjs
CHANGED
|
@@ -182,8 +182,10 @@ async function readStoredEvents(sp, id) {
|
|
|
182
182
|
// handle 基线 header/事件规范化(0.4.0 checkout 实测):checkout 后端给所有
|
|
183
183
|
// 产物盖当前格式版本的文件名,并要求 header.version 等于后端当前
|
|
184
184
|
// SESSION_FORMAT_VERSION、isSeeded 显式给出;读取时还会按当前格式语义校验
|
|
185
|
-
// assistant/message 的 model source
|
|
186
|
-
//
|
|
185
|
+
// assistant/message 的 model source 必须是非空字符串,且自格式 v2 起
|
|
186
|
+
// data.stream 必须是数组(V3 的 Session.fromRestore 恢复边界断言
|
|
187
|
+
// Array.isArray(data.stream),缺字段的日志可写出但不可续聊)。旧基线不需要
|
|
188
|
+
// 这些,规范化只发生在 handle 路径。
|
|
187
189
|
|
|
188
190
|
const handleFormatVersionCache = new WeakMap()
|
|
189
191
|
|
|
@@ -235,33 +237,40 @@ async function normalizeHandleHeader(sp, meta) {
|
|
|
235
237
|
|
|
236
238
|
/**
|
|
237
239
|
* handle 基线的事件批规范化:当前格式语义要求 assistant/message 的 model
|
|
238
|
-
* source
|
|
239
|
-
*
|
|
240
|
-
*
|
|
240
|
+
* source 是非空字符串,且自格式 v2 起 data.stream 必须是数组(V3 的
|
|
241
|
+
* Session.fromRestore 恢复边界要求 Array.isArray(stream):缺 stream 的日志
|
|
242
|
+
* 能写入、能原样读回,但 resume/fork 会响亮抛 invalid settlement fields)。
|
|
243
|
+
* 缺 model 的源记录(真实 Claude transcript 恒有 message.model,仅防御合成/
|
|
244
|
+
* 历史记录)回退 provider 字符串。stream 只在后端当前格式版本 >= 2 时补空
|
|
245
|
+
* 数组——v0/v1 的冻结清单不接受该字段,旧基线必须保持逐字节不变。未改动时
|
|
246
|
+
* 原样返回调用方数组。
|
|
241
247
|
* @param events - 事件批。
|
|
248
|
+
* @param formatVersion - 后端当前会话格式版本(currentHandleFormatVersion)。
|
|
242
249
|
* @returns 规范化后的事件批。
|
|
243
250
|
*/
|
|
244
|
-
function normalizeHandleEvents(events) {
|
|
251
|
+
function normalizeHandleEvents(events, formatVersion) {
|
|
252
|
+
const needsStream = typeof formatVersion === 'number' && formatVersion >= 2
|
|
245
253
|
let changed = false
|
|
246
254
|
const out = events.map((event) => {
|
|
247
255
|
if (event?.type !== 'assistant/message') return event
|
|
248
|
-
const
|
|
249
|
-
if (
|
|
256
|
+
const data = event.data
|
|
257
|
+
if (data === null || typeof data !== 'object' || Array.isArray(data)) return event
|
|
258
|
+
const source = data.message?.source
|
|
259
|
+
const fixModel = source !== null && typeof source === 'object'
|
|
250
260
|
&& source.kind === 'model'
|
|
251
|
-
&& (typeof source.model !== 'string' || source.model.length === 0)
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
},
|
|
261
|
+
&& (typeof source.model !== 'string' || source.model.length === 0)
|
|
262
|
+
const fixStream = needsStream && !Array.isArray(data.stream)
|
|
263
|
+
if (!fixModel && !fixStream) return event
|
|
264
|
+
changed = true
|
|
265
|
+
const nextData = { ...data }
|
|
266
|
+
if (fixStream) nextData.stream = []
|
|
267
|
+
if (fixModel) {
|
|
268
|
+
nextData.message = {
|
|
269
|
+
...data.message,
|
|
270
|
+
source: { ...source, model: typeof source.provider === 'string' && source.provider.length > 0 ? source.provider : 'claude-code' },
|
|
262
271
|
}
|
|
263
272
|
}
|
|
264
|
-
return event
|
|
273
|
+
return { ...event, data: nextData }
|
|
265
274
|
})
|
|
266
275
|
return changed ? out : events
|
|
267
276
|
}
|
|
@@ -1160,7 +1169,8 @@ async function persistConvertedInner(ctx, converted, args, persisted, sourcePath
|
|
|
1160
1169
|
/**
|
|
1161
1170
|
* append 一份事件批次(双基线);服务缺失响亮抛出。handle 路径
|
|
1162
1171
|
* open(id, 'write') 独占单写所有权,append 后必须 flush()(耐久屏障)并
|
|
1163
|
-
* 成对 close()(释放所有权);事件批经 normalizeHandleEvents
|
|
1172
|
+
* 成对 close()(释放所有权);事件批经 normalizeHandleEvents 按后端当前格式
|
|
1173
|
+
* 版本规范化(>= 2 时给 assistant/message 补 stream,否则 V3 恢复边界拒绝)。
|
|
1164
1174
|
* 已被他人持有时 open 响亮拒绝(单写冲突)。
|
|
1165
1175
|
*/
|
|
1166
1176
|
async function spAppend(ctx, id, events) {
|
|
@@ -1174,7 +1184,8 @@ async function spAppend(ctx, id, events) {
|
|
|
1174
1184
|
}
|
|
1175
1185
|
const handle = await sp.open(id, 'write')
|
|
1176
1186
|
try {
|
|
1177
|
-
await
|
|
1187
|
+
const version = await currentHandleFormatVersion(sp)
|
|
1188
|
+
await handle.append(normalizeHandleEvents(events, version))
|
|
1178
1189
|
await handle.flush()
|
|
1179
1190
|
} finally {
|
|
1180
1191
|
await handle.close()
|
|
@@ -1191,10 +1202,11 @@ async function spAppend(ctx, id, events) {
|
|
|
1191
1202
|
* create + append 一份完整会话日志(双基线);服务缺失/落盘失败响亮抛出。
|
|
1192
1203
|
* handle 路径:按服务形状先探测(有 open 即 handle),create 前经
|
|
1193
1204
|
* normalizeHandleHeader 盖当前格式版本与 isSeeded(checkout 后端要求),
|
|
1194
|
-
* create 返回值实测判定(isSessionHandle
|
|
1195
|
-
*
|
|
1196
|
-
*
|
|
1197
|
-
*
|
|
1205
|
+
* create 返回值实测判定(isSessionHandle),事件批经 normalizeHandleEvents 按
|
|
1206
|
+
* 后端当前格式版本规范化(>= 2 时补 assistant/message.stream),append 后
|
|
1207
|
+
* flush() 并在 finally 成对 close()——任何失败路径都释放单写所有权;空事件
|
|
1208
|
+
* 批次(流式导入的首个 create)只 flush 物化空会话。旧路径 create+append 调用
|
|
1209
|
+
* 序列与 0.3.x 逐字节一致(header/事件不做任何规范化)。
|
|
1198
1210
|
*/
|
|
1199
1211
|
async function spPersist(ctx, meta, events) {
|
|
1200
1212
|
const sp = ctx.get('sessionPersistence')
|
|
@@ -1206,7 +1218,10 @@ async function spPersist(ctx, meta, events) {
|
|
|
1206
1218
|
if (isSessionHandle(created)) {
|
|
1207
1219
|
notePersistenceShape(sp, 'handle')
|
|
1208
1220
|
try {
|
|
1209
|
-
if (events.length > 0)
|
|
1221
|
+
if (events.length > 0) {
|
|
1222
|
+
const version = await currentHandleFormatVersion(sp)
|
|
1223
|
+
await created.append(normalizeHandleEvents(events, version))
|
|
1224
|
+
}
|
|
1210
1225
|
await created.flush()
|
|
1211
1226
|
} finally {
|
|
1212
1227
|
await created.close()
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-claude-move",
|
|
3
3
|
"description": "Four-source migration wizard: copy Claude Code, Codex, OpenCode and Hermes sessions, memories, skills, instructions and slash commands into DeepSeek Harness as resumable sessions — copy-only, approval-gated, idempotent",
|
|
4
|
-
"version": "0.4.
|
|
4
|
+
"version": "0.4.6",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./index.mjs",
|
|
7
7
|
"exports": {
|
|
@@ -65,9 +65,7 @@
|
|
|
65
65
|
"filesystem:write"
|
|
66
66
|
],
|
|
67
67
|
"compatibility": {
|
|
68
|
-
"dshVersions": [
|
|
69
|
-
"0.1.2-rc.1"
|
|
70
|
-
]
|
|
68
|
+
"dshVersions": ["0.1.2-rc.1","0.1.5-rc.1"]
|
|
71
69
|
},
|
|
72
70
|
"capability": {
|
|
73
71
|
"id": "move-wizard",
|
|
@@ -84,7 +82,7 @@
|
|
|
84
82
|
},
|
|
85
83
|
"peerDependencies": {
|
|
86
84
|
"@deepseek-ai/cordis": "^4.0.2",
|
|
87
|
-
"@deepseek-ai/dsh-tools": ">=0.1.2-rc.1 <0.2.0",
|
|
85
|
+
"@deepseek-ai/dsh-tools": ">=0.1.2-rc.1 <0.2.0 || >=0.1.5-alpha.1 <0.2.0",
|
|
88
86
|
"@deepseek-ai/schemastery": "^3.18.2"
|
|
89
87
|
},
|
|
90
88
|
"scripts": {
|
|
@@ -112,21 +110,21 @@
|
|
|
112
110
|
"@deepseek-ai/cordis": "^4.0.2",
|
|
113
111
|
"@deepseek-ai/cordis-plugin-include": "^1.0.7",
|
|
114
112
|
"@deepseek-ai/cordis-plugin-loader": "^1.0.3",
|
|
115
|
-
"@deepseek-ai/dsh-agent": "0.1.
|
|
116
|
-
"@deepseek-ai/dsh-attachment": "0.1.
|
|
117
|
-
"@deepseek-ai/dsh-brand": "0.1.
|
|
118
|
-
"@deepseek-ai/dsh-code-runtime": "0.1.
|
|
119
|
-
"@deepseek-ai/dsh-commands": "0.1.
|
|
120
|
-
"@deepseek-ai/dsh-invariants": "0.1.
|
|
121
|
-
"@deepseek-ai/dsh-llm": "0.1.
|
|
122
|
-
"@deepseek-ai/dsh-scope": "0.1.
|
|
123
|
-
"@deepseek-ai/dsh-session": "0.1.
|
|
124
|
-
"@deepseek-ai/dsh-session-projection": "0.1.
|
|
125
|
-
"@deepseek-ai/dsh-system-prompt": "0.1.
|
|
126
|
-
"@deepseek-ai/dsh-timeout": "0.1.
|
|
127
|
-
"@deepseek-ai/dsh-tools": "0.1.
|
|
128
|
-
"@deepseek-ai/dsh-typert-protocol": "0.1.
|
|
129
|
-
"@deepseek-ai/dsh-user-approval": "0.1.
|
|
113
|
+
"@deepseek-ai/dsh-agent": "0.1.5-rc.1",
|
|
114
|
+
"@deepseek-ai/dsh-attachment": "0.1.5-rc.1",
|
|
115
|
+
"@deepseek-ai/dsh-brand": "0.1.5-rc.1",
|
|
116
|
+
"@deepseek-ai/dsh-code-runtime": "0.1.5-rc.1",
|
|
117
|
+
"@deepseek-ai/dsh-commands": "0.1.5-rc.1",
|
|
118
|
+
"@deepseek-ai/dsh-invariants": "0.1.5-rc.1",
|
|
119
|
+
"@deepseek-ai/dsh-llm": "0.1.5-rc.1",
|
|
120
|
+
"@deepseek-ai/dsh-scope": "0.1.5-rc.1",
|
|
121
|
+
"@deepseek-ai/dsh-session": "0.1.5-rc.1",
|
|
122
|
+
"@deepseek-ai/dsh-session-projection": "0.1.5-rc.1",
|
|
123
|
+
"@deepseek-ai/dsh-system-prompt": "0.1.5-rc.1",
|
|
124
|
+
"@deepseek-ai/dsh-timeout": "0.1.5-rc.1",
|
|
125
|
+
"@deepseek-ai/dsh-tools": "0.1.5-rc.1",
|
|
126
|
+
"@deepseek-ai/dsh-typert-protocol": "0.1.5-rc.1",
|
|
127
|
+
"@deepseek-ai/dsh-user-approval": "0.1.5-rc.1",
|
|
130
128
|
"oxlint": "^0.18.1"
|
|
131
129
|
},
|
|
132
130
|
"funding": {
|