dsh-claude-move 0.2.1
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 +73 -0
- package/LICENSE +201 -0
- package/NOTICE +23 -0
- package/README.es.md +291 -0
- package/README.hi.md +292 -0
- package/README.md +317 -0
- package/README.pt.md +291 -0
- package/README.zh.md +311 -0
- package/THIRD_PARTY_NOTICES.md +67 -0
- package/assets/social-card.png +0 -0
- package/client/client.js +451 -0
- package/cordis.patch.yml +5 -0
- package/index.mjs +2891 -0
- package/lib/agmd-section.mjs +144 -0
- package/lib/commands-migrate.mjs +85 -0
- package/lib/context.mjs +156 -0
- package/lib/convert.mjs +725 -0
- package/lib/discovery.mjs +619 -0
- package/lib/frontmatter.mjs +58 -0
- package/lib/handoff.mjs +136 -0
- package/lib/imports-store.mjs +64 -0
- package/lib/manifest.mjs +73 -0
- package/lib/persona.mjs +37 -0
- package/lib/report.mjs +63 -0
- package/lib/settings.mjs +147 -0
- package/lib/skill-migrate.mjs +128 -0
- package/lib/skills-provider.mjs +219 -0
- package/lib/sources/claude/mapper.mjs +102 -0
- package/lib/sources/claude/parser.mjs +190 -0
- package/lib/sources/codex/mapper.mjs +120 -0
- package/lib/sources/codex/parser.mjs +451 -0
- package/lib/sources/contract.mjs +145 -0
- package/lib/sources/hermes/mapper.mjs +61 -0
- package/lib/sources/hermes/parser.mjs +152 -0
- package/lib/sources/opencode/convert.mjs +236 -0
- package/lib/sources/opencode/mapper.mjs +102 -0
- package/lib/sources/opencode/parser.mjs +266 -0
- package/lib/wizard.mjs +329 -0
- package/package.json +66 -0
package/README.pt.md
ADDED
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
# dsh-claude-move
|
|
2
|
+
|
|
3
|
+
**Mantenha seu histórico do Claude Code ao migrar para o DeepSeek Harness.** Uma única instalação copia cada sessão, memória, habilidade e `CLAUDE.md` do Claude para o DSH como sessões retomáveis — organizadas em um workspace `claudecode` dedicado (um workspace por projeto é opcional via config).
|
|
4
|
+
|
|
5
|
+
`Somente cópia` · `Retomada sem interrupções` · `Workspaces por projeto` · `Sincronização ao vivo com o Claude Code`
|
|
6
|
+
|
|
7
|
+
[](https://github.com/PerryLink/dsh-claude-move/actions/workflows/test.yml)
|
|
8
|
+
[](https://www.npmjs.com/package/dsh-claude-move)
|
|
9
|
+
[](https://www.npmjs.com/package/dsh-claude-move)
|
|
10
|
+
[](https://nodejs.org)
|
|
11
|
+
[](LICENSE)
|
|
12
|
+
[](https://github.com/topics/dsh)
|
|
13
|
+
[](https://github.com/topics/dsh-plugin)
|
|
14
|
+
[](https://github.com/PerryLink/dsh-claude-move/issues)
|
|
15
|
+
|
|
16
|
+

|
|
17
|
+
|
|
18
|
+
[English](README.md) | [中文](README.zh.md) | [Español](README.es.md) | Português | [हिन्दी](README.hi.md)
|
|
19
|
+
|
|
20
|
+
> Prévia de desenvolvimento (0.1.0). Roteiro e design: [PLAN.md](PLAN.md) · histórico de mudanças: [CHANGELOG.md](CHANGELOG.md).
|
|
21
|
+
|
|
22
|
+
## ✨ Recursos
|
|
23
|
+
|
|
24
|
+
- 🔍 **Descoberta automática** — localiza a raiz de dados do Claude (`$CLAUDE_CONFIG_DIR`, padrão `~/.claude`) e indexa cada projeto/sessão (título, marcas de tempo, contagens), estado do diretório e do git, memórias, habilidades, `CLAUDE.md` global e `settings.json` — com cache incremental que só relê arquivos alterados.
|
|
25
|
+
- 📥 **Importação de histórico com fidelidade total** — sessões DSH equilibradas e retomáveis (`turn/start → step/start → user/message → assistant/message → tool/call → tool/result → step/end → turn/end`), linhas malformadas com número de linha. Chamadas de ferramenta interrompidas são reparadas para que cada `tool_use` tenha exatamente um resultado (sem mais 400s permanentes ao retomar).
|
|
26
|
+
- 🗂 **Um workspace `claudecode` (padrão)** — toda sessão importada fica em um workspace "claudecode" dedicado, enraizado em uma pasta nova (`$DSH_HOME/claudecode` por padrão; a única coisa que o plugin cria). `workspaceMode: 'per-project'` restaura o agrupamento de um workspace por projeto.
|
|
27
|
+
- 🔁 **Somente cópia e incremental** — nada é movido, reescrito ou excluído em nenhum lado. Reexecutar a importação apenas anexa os novos turnos à mesma sessão DSH; `force: true` salva uma cópia completa adicional com um novo id.
|
|
28
|
+
- 🧠 **Contexto pessoal sempre atualizado** — memórias injetadas como seção ao vivo (projeto atual primeiro, `memoryScope`), habilidades do Claude como habilidades reais do DSH (global **e por projeto** `.claude/skills`, documentos que não são habilidades como `README.md` são ignorados), `CLAUDE.md` global + de projeto injetado cedo. Mesmo no workspace `claudecode`, o diretório original do projeto é lembrado para a resolução de memória/`CLAUDE.md`.
|
|
29
|
+
- ⚡ **Sincronização ao vivo com o Claude Code** — continue usando o Claude Code em paralelo; cada reexecução traz apenas o que mudou.
|
|
30
|
+
- 🖥 **Painel web e comandos de um passo** — `/claude-import-all`, `/resume-claude` e um painel de migração flutuante com progresso.
|
|
31
|
+
- 🪄 **Assistente de migração de quatro fontes (0.2.1)** — um assistente `/move` mais as ferramentas `move_detect` / `move_preview` / `move_run` migram Claude Code, Codex, OpenCode e Hermes: memórias/instruções viram seções gerenciadas do `AGENTS.md`, skills viram skills reais do DSH, comandos slash viram comandos do DSH e sessões viram sessões retomáveis — com porta de aprovação, idempotente (`move.json`) e conflitos exibidos como diff, sem adivinhar.
|
|
32
|
+
- 🛡 **Segurança em primeiro lugar** — arquivos fonte estritamente somente leitura, logs do DSH append-only, segredos informados apenas por posição, registros de permissão contados mas nunca importados.
|
|
33
|
+
|
|
34
|
+
## 🚀 Início rápido
|
|
35
|
+
|
|
36
|
+
```sh
|
|
37
|
+
# 1. Instalar
|
|
38
|
+
dsh plugin --profile web add -w github:PerryLink/dsh-claude-move
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
2. Em qualquer sessão do DSH, rode um comando:
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
/claude-import-all # varrer → copiar todas as sessões do Claude → relatório
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
3. Atualize uma vez a página web já aberta (o painel tem o botão «Atualizar lista de sessões») e clique em qualquer sessão importada para continuar. **Não é preciso reiniciar o DSH** — veja [Depois de importar](#-depois-de-importar).
|
|
48
|
+
|
|
49
|
+
Prefere controle fino?
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
claude_scan # índice estruturado de todos os projetos/sessões
|
|
53
|
+
import_claude { path: "~/.claude/projects" } # um diretório de projeto (recursivo)
|
|
54
|
+
import_claude { path: "all" } # tudo
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## 🪄 Assistente de migração de quatro fontes
|
|
58
|
+
|
|
59
|
+
```text
|
|
60
|
+
/move # assistente em um passo: detectar → pré-visualizar → executar → relatar (as quatro fontes)
|
|
61
|
+
move_detect # escaneia Claude Code / Codex / OpenCode / Hermes
|
|
62
|
+
move_preview # plano por item: new | unchanged | changed | conflict (com diff) | unsupported
|
|
63
|
+
move_run # executa após a porta de aprovação; resolução: skip | overwrite | rename | merge (skip por padrão, nunca adivinha)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
- **Fontes** — Claude Code (`~/.claude`), Codex (`~/.codex`), OpenCode (raízes de dados + configuração), Hermes (raízes de skills/memória); cada fonte tem seu próprio parser e mapper.
|
|
67
|
+
- **Mapeamento** — memórias/instruções → seções gerenciadas somente de acréscimo no `AGENTS.md` global do DSH (uma seção marcada por item); skills → skills reais do DSH (bundles `SKILL.md` copiados como estão, outros formatos convertidos); comandos slash → comandos registrados do DSH (os prompts são reconstruídos do `move.json` após reiniciar); sessões → sessões retomáveis do DSH (os mesmos importadores da fase 1).
|
|
68
|
+
- **Idempotente** — cada plano aplicado é registrado em `$DSH_HOME/claude-move/move.json` (`digest` / `targetDigest` / `appliedAt`); reexecuções pulam o que não mudou e `force` reaplica.
|
|
69
|
+
- **Porta de aprovação** — uma execução que for escrever algo pergunta primeiro ao `ctx.approval`; qualquer coisa diferente de `allowed-once` significa zero escritas.
|
|
70
|
+
|
|
71
|
+
## 🗂 O que é migrado
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
~/.claude (somente leitura)
|
|
75
|
+
├─ projects/*/*.jsonl ──→ sessões DSH retomáveis, agrupadas em um workspace "claudecode" (padrão)
|
|
76
|
+
├─ projects/*/memory/ ──→ seção de memória ao vivo do prompt do sistema (relida por requisição)
|
|
77
|
+
├─ skills/** ──→ habilidades reais do DSH
|
|
78
|
+
└─ CLAUDE.md + settings ──→ seção inicial do prompt + sugestões de configuração (nunca auto-aplicadas)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
| No Claude Code | Aterrissa no DSH como |
|
|
82
|
+
| --- | --- |
|
|
83
|
+
| Transcrições de sessão (`projects/*/*.jsonl`) | Sessões DSH equilibradas e retomáveis — mapeamento fiel de `user`/`assistant`/`tool`/`thinking` com reparo de chamadas de ferramenta interrompidas — agrupadas em um workspace **`claudecode`** (padrão `$DSH_HOME/claudecode`) ou um workspace por projeto (`workspaceMode: 'per-project'`) |
|
|
84
|
+
| Arquivos de memória (`projects/*/memory/*.md`) | Uma seção de contexto do prompt do sistema ao vivo, relida a cada requisição (`feedback > project > reference > user`) — o diretório original do projeto é lembrado mesmo dentro do workspace `claudecode` |
|
|
85
|
+
| Habilidades (`~/.claude/skills/**`) | Habilidades reais do DSH (nomes kebab-case, colisões com sufixo, máximo 30 por padrão; `README.md`/`MEMORY.md` e arquivos sem descrição são ignorados) |
|
|
86
|
+
| `CLAUDE.md` (global + por projeto) | Uma seção inicial do prompt; o arquivo do projeto vence |
|
|
87
|
+
| `settings.json` | Sugestões de configuração do DSH com lista explícita de chaves não mapeáveis |
|
|
88
|
+
| Estado do projeto (diretório, branch do git e arquivos modificados) | Visível no índice de varredura, nos selos do painel web e no handoff do `/resume-claude` |
|
|
89
|
+
|
|
90
|
+
## 📦 Instalação
|
|
91
|
+
|
|
92
|
+
```sh
|
|
93
|
+
# Do GitHub
|
|
94
|
+
dsh plugin --profile web add -w github:PerryLink/dsh-claude-move
|
|
95
|
+
|
|
96
|
+
# Cópia local (desenvolvimento)
|
|
97
|
+
dsh plugin --profile web add -w link:/path/to/dsh-claude-move
|
|
98
|
+
|
|
99
|
+
# De um tarball empacotado
|
|
100
|
+
dsh plugin --profile web add -w ./dsh-claude-move-0.1.0.tgz
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
O pacote é ESM puro, sem etapa de build, então a instalação via Git dispensa o script `prepare` e a lista `allowBuilds`. Consulte o [guia oficial de empacotamento e instalação](https://deepseek-harness.github.io/deepseek-harness/develop/basic/publish).
|
|
104
|
+
|
|
105
|
+
## 🛠 Uso
|
|
106
|
+
|
|
107
|
+
Chame as ferramentas em qualquer sessão com o plugin montado:
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
claude_scan # varredura completa (cache incremental)
|
|
111
|
+
claude_scan { path: "~/.claude/projects/<slug>" } # varredura parcial
|
|
112
|
+
claude_scan { refresh: true } # ignora o cache e varre tudo de novo
|
|
113
|
+
|
|
114
|
+
import_claude { path: "~/.claude/projects/<slug>/<sessionId>.jsonl" } # uma sessão
|
|
115
|
+
import_claude { path: "~/.claude/projects" } # diretório (recursivo)
|
|
116
|
+
import_claude { path: "all" } # tudo
|
|
117
|
+
# Pode rodar de novo quando quiser: arquivos sem mudanças são pulados e transcrições que cresceram anexam apenas os novos turnos.
|
|
118
|
+
import_claude { path: "...", force: true } # nova cópia completa como import-<src>-<n> (a cópia anterior é mantida)
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Comandos (disparados pelo usuário, sem turno do modelo):
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
/claude-import-all # um passo: varrer → importar tudo → relatório → injetar na sessão atual
|
|
125
|
+
/resume-claude latest # continuar a sessão do Claude mais recente
|
|
126
|
+
/resume-claude <sessionId> # pelo id de sessão de origem ou id import-<src>
|
|
127
|
+
/resume-claude <palavra-chave> # busca títulos; múltiplos resultados são listados, nunca adivinhados
|
|
128
|
+
/claude-move-reset # reinicia a cache do plugin (marcadores + mapa de importação); sessões importadas são mantidas
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Painel web: o botão flutuante **🐳 Claude 迁移** (canto inferior direito) abre o painel — árvore de projetos/sessões com selos de estado (não importado / importado / importado-com-turnos-novos / origem ausente / diretório inexistente / git sujo), filtro por palavra-chave, paginação, «Importar e continuar» + «Abrir sessão» + «Atualizar lista de sessões» por sessão, importação em lote com barra de progresso e cancelamento, e botão de reinício de cache. Os textos seguem o idioma do navegador (zh/en). Usa as rotas JSON `/api/claude-move/*` do próprio plugin, registradas no seam público `ctx.webServer`.
|
|
132
|
+
|
|
133
|
+
- **Varredura**: retorna um índice JSON estruturado: projetos (slug/cwd/existência do diretório/branch do git e arquivos modificados), sessões (título/marcas de tempo/contagens/linhas malformadas), memórias, habilidades, CLAUDE.md global e settings.json; cada sessão carrega `import.status` (`none`/`imported`/`source-missing`) e `import.updatesPending` quando há turnos novos não sincronizados. `settingsSuggestions` contém a tradução do settings.json para o DSH e as chaves não mapeáveis (ver [COMPLIANCE.md](COMPLIANCE.md)).
|
|
134
|
+
- **Importação**: mapeia mensagens user/assistant/tool/thinking com fidelidade total; chamadas de ferramenta interrompidas são reparadas (exatamente um resultado por `tool_use`), e o resultado é uma sessão equilibrada e retomável, vinculada ao workspace `claudecode` (padrão) ou ao workspace por projeto. Lotes são resumidos arquivo por arquivo (`imported`/`appended`/`already-imported`/`skipped`/`failed`), linhas malformadas carregam número de linha, segredos suspeitos são informados apenas por posição (arquivo:linha:tipo) e registros de permissão são contados, nunca importados. Importar nunca apaga nem reescreve nada: sessões existentes do DSH ficam intactas, cópias importadas anteriormente são mantidas e os arquivos fonte do Claude nunca são gravados.
|
|
135
|
+
- **O contexto pessoal entra em vigor automaticamente** (sem ação de importação):
|
|
136
|
+
- Memórias: `projects/*/memory/*.md` são injetados como seção dinâmica, relidos a cada requisição (memórias novas valem na hora), ordenados `feedback > project > reference > user`, limite de 8 KiB por padrão. Com `memoryScope: current-project` (padrão) só as memórias do projeto da sessão atual são injetadas (recai em todos os projetos quando o cwd não corresponde a nenhum); `all` injeta tudo com o projeto atual primeiro. Dentro do workspace `claudecode`, o plugin resolve o projeto original a partir do `sourceCwd` registrado.
|
|
137
|
+
- Habilidades: `~/.claude/skills/**/SKILL.md` (mais arquivos planos `*.md`) e `.claude/skills/**` do projeto atual viram habilidades do DSH (nomes normalizados para kebab-case, colisões com sufixo, máximo 30; `README.md`/`MEMORY.md` e arquivos sem descrição são ignorados, para que nunca quebrem o carregamento de habilidades); o DSH cuida do catálogo e da ferramenta `skill`.
|
|
138
|
+
- Instruções: o `~/.claude/CLAUDE.md` global mais o `.claude/CLAUDE.md` da sessão atual são injetados como uma seção inicial (o projeto vence; resolvido via `sourceCwd` dentro do workspace `claudecode`).
|
|
139
|
+
|
|
140
|
+
## ✅ Depois de importar
|
|
141
|
+
|
|
142
|
+
**Não é preciso reiniciar o DSH.** As importações são gravadas de forma durável pelo serviço público `sessionPersistence` assim que terminam:
|
|
143
|
+
|
|
144
|
+
- As listas do servidor (`session.list` / `workspace.list`, a CLI ou qualquer página recém-aberta) mostram imediatamente as sessões importadas sob o workspace **`claudecode`** (um por projeto com `workspaceMode: 'per-project'`).
|
|
145
|
+
- O painel atualiza sozinho a lista de sessões da página já aberta (serviços de cliente do shell `sessions`/`workspaces`, detectados por capacidade) e oferece «Abrir sessão» por sessão importada; em shells antigos sem esses serviços recai no botão «Atualizar lista de sessões» / recarga da página — as importações gravam sessões frias direto no serviço de persistência, então não emitem o frame ao vivo `host/session-added`; os grupos de workspaces, porém, atualizam ao vivo (`host/workspace-changed`).
|
|
146
|
+
- As sessões importadas podem ser abertas, lidas e retomadas na hora — `/resume-claude`, ou clique na sessão da lista. O handoff informa o diretório original do projeto. Reexecutar a importação a qualquer momento apenas anexa os novos turnos às mesmas sessões.
|
|
147
|
+
|
|
148
|
+
## ⚙️ Configuração
|
|
149
|
+
|
|
150
|
+
Tudo opcional e substituível no `cordis.yml`:
|
|
151
|
+
|
|
152
|
+
```yaml
|
|
153
|
+
- id: claude-move
|
|
154
|
+
name: dsh-claude-move
|
|
155
|
+
config:
|
|
156
|
+
claudeHome: null # padrão: $CLAUDE_CONFIG_DIR ou ~/.claude
|
|
157
|
+
workspaceMode: claudecode # 'claudecode' (padrão: um workspace dedicado para todas as importações) | 'per-project' (um workspace por cwd de origem)
|
|
158
|
+
claudecodeDir: null # pasta do workspace claudecode; padrão $DSH_HOME/claudecode (a única pasta que o plugin cria)
|
|
159
|
+
scanGit: true # nível de sondagem git: true completo | 'branch' sem subprocessos | false
|
|
160
|
+
gitTimeoutMs: 5000 # tempo limite do subprocesso git
|
|
161
|
+
scanConcurrency: 8 # limite de concorrência da varredura de projetos
|
|
162
|
+
maxTranscriptBytes: 67108864
|
|
163
|
+
excludeProjects: [] # substrings de slug a ignorar, ex. ['demo-']
|
|
164
|
+
enableMemory: true
|
|
165
|
+
memoryMaxBytes: 8192
|
|
166
|
+
memoryScope: current-project # 'current-project' só o projeto atual | 'all' tudo, atual primeiro
|
|
167
|
+
enableSkills: true
|
|
168
|
+
maxSkills: 30
|
|
169
|
+
extraSkillDirs: []
|
|
170
|
+
enableInstructions: true
|
|
171
|
+
resumeMaxChars: 2048 # limite de caracteres do resumo de transição
|
|
172
|
+
resumeMode: inject # 'inject' resumo de transição | 'agents' ctx.agents.resume
|
|
173
|
+
enableWebPanel: true # registrar as rotas do painel /api/claude-move/*
|
|
174
|
+
importConcurrency: 4 # concorrência de leitura+conversão por lote (o salvamento segue sequencial)
|
|
175
|
+
# Assistente de quatro fontes (0.2.1+):
|
|
176
|
+
requireApproval: true # as escritas do assistente perguntam ao ctx.approval (apenas allowed-once)
|
|
177
|
+
codexHome: null # por padrão: $CODEX_HOME ou ~/.codex
|
|
178
|
+
opencodeDataHome: null # por padrão: diretório de dados XDG da plataforma/opencode
|
|
179
|
+
opencodeConfigHome: null # por padrão: diretório de configuração XDG da plataforma/opencode
|
|
180
|
+
hermesHome: null # por padrão: $HERMES_HOME ou ~/.hermes
|
|
181
|
+
skillsDir: null # destino de skills do assistente; por padrão $DSH_HOME/skills
|
|
182
|
+
agentsMdPath: null # destino de memórias/instruções; por padrão $DSH_HOME/AGENTS.md
|
|
183
|
+
moveWorkspaceMode: per-source # 'per-source' | 'single' agrupamento de espaços de trabalho
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## 🗑 Desinstalação
|
|
187
|
+
|
|
188
|
+
Remova a linha `claude-move` dos bundles do perfil e reinicie o `dsh`. As sessões importadas permanecem no diretório de dados do DSH; o plugin apenas escreve seu cache (`$DSH_HOME/claude-move/`) e a pasta do workspace `claudecode`, e nunca toca os dados fonte do Claude.
|
|
189
|
+
|
|
190
|
+
## 🧭 Compatibilidade
|
|
191
|
+
|
|
192
|
+
- Alvo: `dsh 0.1.0-rc.6` (perfil web); dependências peer fixadas em `0.1.0-rc.6`. Node `^22.19 || >=24`.
|
|
193
|
+
- Última verificação **2026-08-13** no Windows (Node 22) contra `@deepseek-ai/dsh@0.1.0-rc.6`: instalação do zero via tarball, varredura real (40 projetos / 2387 sessões), importação real em lote 13/13 com reimportação idempotente 13/13, vínculo ao workspace e artefatos de persistência confirmados. macOS/Linux cobertos pela matriz CI (linux/macos/windows × Node 22).
|
|
194
|
+
- Verificado **2026-08-14** contra o checkout atual do `deepseek-harness` (perfil web, backend de sessões JSONL+zstd, registro de workspaces real) em um home isolado: boot web completo com o plugin montado, varredura + importação total pelas rotas do painel, criação do workspace `claudecode` com sessões vinculadas, anexo incremental a uma sessão importada existente (seq contíguo, carrega limpo), reimportação segura após reinício e sessões DSH preexistentes intactas o tempo todo. Nenhuma sessão é jamais arquivada, apagada ou reescrita.
|
|
195
|
+
|
|
196
|
+
### Matriz de compatibilidade (apenas seams públicos)
|
|
197
|
+
|
|
198
|
+
| Superfície | Uso | Fallback quando ausente |
|
|
199
|
+
| --- | --- | --- |
|
|
200
|
+
| Serviços host (`tools` / `sessionPersistence` / `workspaceRegistry` / `commands` / `systemPrompt` / `skills` / `webServer`) | usados onde listados | serviços opcionais registram-se reativamente via `internal/service`; `fs` ausente falha em voz alta |
|
|
201
|
+
| `sessionPersistence.listSnapshots` / `readFrom`, `fs.streamText`, `ctx.jobs`, `ctx.agents.resume` | detectados por capacidade | `list()` / leitura completa com rejeição em voz alta / tabela de jobs própria / injeção do resumo |
|
|
202
|
+
| Serviços de cliente do shell (`sessions.refresh/open`, `workspaces.refresh`) | detectados no apply do painel | recarga completa da página |
|
|
203
|
+
| Novas capacidades da plataforma nunca são requisitos duros — o plugin sempre inicia no rc.6. | | |
|
|
204
|
+
|
|
205
|
+
## 🔐 Permissões e dados
|
|
206
|
+
|
|
207
|
+
- **Lê** `~/.claude` (transcrições, memórias, habilidades, CLAUDE.md, settings.json) — estritamente somente leitura — e os diretórios de projeto para os quais importa (vínculo ao workspace no modo `per-project`).
|
|
208
|
+
- **Escreve** os logs de sessão do DSH pelo serviço público `sessionPersistence` — apenas create + append, nunca apaga, reescreve ou arquiva sessões existentes — registros do registro de workspaces, seu próprio cache em `$DSH_HOME/claude-move/` (marcadores de varredura + mapa de importação), e a pasta do workspace `claudecode` (`$DSH_HOME/claudecode` por padrão; um simples `mkdir`, nunca qualquer exclusão).
|
|
209
|
+
- **Nunca** modifica os arquivos fonte do Claude, toca dados de outros aplicativos nem acessa a rede.
|
|
210
|
+
- **Nenhuma credencial** é lida ou transmitida; segredos suspeitos nas transcrições são informados apenas por posição.
|
|
211
|
+
|
|
212
|
+
## 🛡 Limites de segurança
|
|
213
|
+
|
|
214
|
+
- Arquivos fonte são estritamente somente leitura; logs de sessão do DSH são append-only (apenas `create` + `append`).
|
|
215
|
+
- Transcrições externas são entrada não confiável: nada nelas é executado; conteúdo system/developer/thinking nunca entra no resumo de transição.
|
|
216
|
+
- Sem mudanças no motor do DSH, pacotes oficiais de UI ou apiproxy — apenas serviços públicos (`sessionPersistence` / `workspaceRegistry` / `tools` / `commands` / `systemPrompt` / `skills` / `webServer`).
|
|
217
|
+
- Segredos suspeitos são informados apenas por localização (nunca seu conteúdo); registros `permission`/`permission-mode`/`queue-operation` são contados, não importados.
|
|
218
|
+
|
|
219
|
+
## 🩺 Solução de problemas
|
|
220
|
+
|
|
221
|
+
- Linha sem efeito: `dsh --profile <p> --dump-config` deve imprimir `# == dsh-claude-move`; execute `dsh plugin --profile <p> add -w ...` novamente.
|
|
222
|
+
- A web inicia mas trava em silêncio: perfis novos inicializados por `dsh plugin add` contêm apenas `dsh-base` — adicione `@deepseek-ai/dsh-web-app` em `dsh.profile.bundles`. Instalar no perfil `web` existente não precisa de nada.
|
|
223
|
+
- Rotas do painel 404: só são servidas quando `enableWebPanel: true` e um servidor web está composto; verifique o log de boot por fibras FAILED.
|
|
224
|
+
- A importação falha com "transcript 过大": aumente `maxTranscriptBytes` ou importe esse arquivo individualmente.
|
|
225
|
+
- A importação teve sucesso mas a barra lateral não mostra a nova sessão: a página já estava aberta — clique uma vez em «Atualizar lista de sessões» do painel (ou recarregue a página). Nunca é preciso reiniciar o DSH.
|
|
226
|
+
- Logs: falhas de boot são impressas no console do `dsh`; o plugin registra erros com o prefixo `[claude-move]` para problemas de workspace/mapa de importação.
|
|
227
|
+
|
|
228
|
+
## 📚 Documentação
|
|
229
|
+
|
|
230
|
+
- [PLAN.md](PLAN.md) — conclusões da pesquisa e plano de implementação.
|
|
231
|
+
- [ARCHITECTURE.md](ARCHITECTURE.md) — diagrama de arquitetura e tabela completa de mapeamento de dados.
|
|
232
|
+
- [COMPLIANCE.md](COMPLIANCE.md) — auditoria cláusula por cláusula frente às restrições oficiais de plugins (repo e docs do deepseek-harness, [deepseek.com/harness](https://www.deepseek.com/harness/), a [documentação de desenvolvimento](https://deepseek-harness.github.io/deepseek-harness/develop/basic/), [Cordis](https://github.com/cordiverse/cordis) e o [paper do Cordis](https://github.com/cordiverse/paper)).
|
|
233
|
+
- [OPTIMIZATION.md](OPTIMIZATION.md) — linhas de base medidas e candidatos de otimização ordenados.
|
|
234
|
+
- [RELEASE.md](RELEASE.md) — checklist de release com evidência de aceitação.
|
|
235
|
+
- [CHANGELOG.md](CHANGELOG.md) — o que mudou em cada versão.
|
|
236
|
+
|
|
237
|
+
## 🙏 Atribuição (componentes open source)
|
|
238
|
+
|
|
239
|
+
Este projeto está licenciado sob a Apache License 2.0; os seguintes componentes sob MIT conservam suas próprias licenças (texto completo em [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md)):
|
|
240
|
+
|
|
241
|
+
- Núcleo de conversão vendored de [Nwflower/dsh-chat-import](https://github.com/Nwflower/dsh-chat-import) (MIT).
|
|
242
|
+
- Convenções de descoberta e modelo de segurança de [Demogorgon314/dsh-resume-plugin](https://github.com/Demogorgon314/dsh-resume-plugin) (MIT; seu `session_reader.py` tem origem Apache-2.0 — ver [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md)).
|
|
243
|
+
- Padrões de injeção de memory/skills e análise de frontmatter de [YYTbit/dsh-plugin-claude-bridge](https://github.com/YYTbit/dsh-plugin-claude-bridge) (MIT).
|
|
244
|
+
|
|
245
|
+
## 🧑💻 Desenvolvimento
|
|
246
|
+
|
|
247
|
+
```sh
|
|
248
|
+
npm install # peer deps: @deepseek-ai/cordis, @deepseek-ai/dsh-tools@0.1.0-rc.6, @deepseek-ai/schemastery
|
|
249
|
+
npm test # node --test: convert (vendored + estendido), discovery, import/report, context, settings
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
O CI roda a suíte completa no Node 22 via GitHub Actions ([test.yml](.github/workflows/test.yml)).
|
|
253
|
+
|
|
254
|
+
## 🧠 Model Experience
|
|
255
|
+
|
|
256
|
+
- A superfície visível ao modelo são as descrições/esquemas das duas ferramentas e suas saídas: `claude_scan` devolve o índice estruturado, `import_claude` devolve resumos por arquivo com posições de avisos. Os resultados das ferramentas são eles próprios eventos `tool/result` registrados, então tudo é reconstruível.
|
|
257
|
+
- Nenhum texto oculto visível ao modelo; as seções memory/CLAUDE.md ficam registradas em `ctx.systemPrompt` (montagem do prompt, reconstruível a partir do log de sessão).
|
|
258
|
+
|
|
259
|
+
## ⚠️ Limitações conhecidas
|
|
260
|
+
|
|
261
|
+
- Títulos vêm de `custom-title`/`ai-title`/primeiro prompt; registros `summary` do Claude não são usados como títulos.
|
|
262
|
+
- Blocos `thinking` são mantidos no log importado como conteúdo `reasoning`, mas nunca entram no resumo de transição.
|
|
263
|
+
- Chamadas de ferramenta interrompidas são reparadas com um resultado de erro sintético (nunca descartadas), então sessões com interrupções no meio do turno continuam retomáveis — o reparo é reportado no resultado da importação (`repaired.synthesized`).
|
|
264
|
+
- Registros de permissão são contados, não importados; sugestões de presets de permissão do DSH são geradas nos relatórios.
|
|
265
|
+
- Transcrições maiores que `maxTranscriptBytes` são importadas por streaming em blocos quando o host oferece `fs.streamText` (memória O(bloco)); sem essa superfície falham em voz alta em vez de importação parcial (fidelidade primeiro).
|
|
266
|
+
- Registros `summary` do Claude são informados, mas não mapeados para nós de compactação do DSH (ver OPTIMIZATION.md); o histórico completo é importado como turnos originais.
|
|
267
|
+
- Em `workspaceMode: 'per-project'`, sessões cujo diretório de origem foi excluído ainda importam, mas o vínculo ao workspace falha (ficam sem grupo; `workspace.attached: false` mais um `reason` no relatório). O workspace `claudecode` padrão não depende do diretório de origem, então essas sessões se vinculam normalmente nele.
|
|
268
|
+
- Importações em lote interrompidas podem ser reexecutadas com segurança (idempotente, append-only): arquivos concluídos são pulados e os que cresceram anexam apenas os novos turnos.
|
|
269
|
+
- Se uma transcrição foi truncada ou reiniciada no lugar (menos turnos que a importação registrada), a reimportação a pula e reporta `sourceShrunk`; use `force: true` para uma cópia completa nova.
|
|
270
|
+
- O painel web é um painel flutuante sem build, dirigido pelas rotas JSON do próprio plugin; não usa o sistema interno de slots de UI do shell (mantido independente dos internals não documentados do rc.6).
|
|
271
|
+
|
|
272
|
+
## 🤝 Contribuir e dar feedback
|
|
273
|
+
|
|
274
|
+
Issues e pull requests são bem-vindos — use os modelos fornecidos ([relato de bug](.github/ISSUE_TEMPLATE/bug-report.yml), [solicitação de recurso](.github/ISSUE_TEMPLATE/feature-request.yml)). Perguntas e discussões ficam nas [GitHub Discussions](https://github.com/PerryLink/dsh-claude-move/discussions) do repo. Reporte problemas de segurança em particular via GitHub Security Advisories (repo Settings → Security; veja [SECURITY.md](SECURITY.md)).
|
|
275
|
+
|
|
276
|
+
## 💛 Colaboradores
|
|
277
|
+
|
|
278
|
+
Obrigado a todos que ajudaram a melhorar este plugin:
|
|
279
|
+
|
|
280
|
+
- [OLDnana1](https://github.com/OLDnana1) — análise da causa raiz da corrupção por chamadas de ferramenta interrompidas, que fazia as sessões importadas retornarem HTTP 400 permanentemente ao retomar ([#1](https://github.com/PerryLink/dsh-claude-move/issues/1)); corrigido na v0.2.0.
|
|
281
|
+
- [GooodWei](https://github.com/GooodWei) — identificou que `README.md` (e qualquer `.md` sem descrição) era registrado erroneamente como skill, quebrando todo o carregamento de skills do DSH ([#1](https://github.com/PerryLink/dsh-claude-move/issues/1)); corrigido na v0.2.0.
|
|
282
|
+
- Os projetos MIT upstream reutilizados por este plugin são creditados em [Atribuição](#-attribution-open-source-components) e em [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md).
|
|
283
|
+
|
|
284
|
+
## 🔗 Links relacionados
|
|
285
|
+
|
|
286
|
+
- DeepSeek Harness: [repo](https://github.com/deepseek-ai/deepseek-harness) · [site](https://www.deepseek.com/harness/) · [documentação de desenvolvimento](https://deepseek-harness.github.io/deepseek-harness/develop/basic/)
|
|
287
|
+
- Ecossistema de plugins: [tópico `dsh`](https://github.com/topics/dsh) · [tópico `dsh-plugin`](https://github.com/topics/dsh-plugin) · [Discord](https://discord.gg/Ycq5dCaS4)
|
|
288
|
+
|
|
289
|
+
## 📄 Licença
|
|
290
|
+
|
|
291
|
+
Apache License 2.0 — ver [LICENSE](LICENSE) e [NOTICE](NOTICE). Avisos de terceiros (incluindo o texto MIT dos componentes MIT) em [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md).
|
package/README.zh.md
ADDED
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
# dsh-claude-move
|
|
2
|
+
|
|
3
|
+
**迁移到 DeepSeek Harness,不丢 Claude Code 历史。** 一次安装,把 Claude 的全部会话、记忆、技能与 `CLAUDE.md` **复制**进 DSH,生成可续聊的会话——并归入专用 `claudecode` 工作区(按项目各建工作区为可选配置)。
|
|
4
|
+
|
|
5
|
+
`复制式迁移` · `无缝续聊` · `按项目划分工作区` · `与 Claude Code 实时同步`
|
|
6
|
+
|
|
7
|
+
[](https://github.com/PerryLink/dsh-claude-move/actions/workflows/test.yml)
|
|
8
|
+
[](https://www.npmjs.com/package/dsh-claude-move)
|
|
9
|
+
[](https://www.npmjs.com/package/dsh-claude-move)
|
|
10
|
+
[](https://nodejs.org)
|
|
11
|
+
[](LICENSE)
|
|
12
|
+
[](https://github.com/topics/dsh)
|
|
13
|
+
[](https://github.com/topics/dsh-plugin)
|
|
14
|
+
[](https://github.com/PerryLink/dsh-claude-move/issues)
|
|
15
|
+
|
|
16
|
+

|
|
17
|
+
|
|
18
|
+
[English](README.md) | 中文 | [Español](README.es.md) | [Português](README.pt.md) | [हिन्दी](README.hi.md)
|
|
19
|
+
|
|
20
|
+
> 开发者预览版(0.1.0)。路线图与设计:[PLAN.md](PLAN.md) · 变更记录:[CHANGELOG.md](CHANGELOG.md)。
|
|
21
|
+
|
|
22
|
+
## ✨ 特性
|
|
23
|
+
|
|
24
|
+
- 🔍 **自动发现** —— 定位 Claude 数据根目录(`$CLAUDE_CONFIG_DIR`,缺省 `~/.claude`),索引全部项目/会话(标题、起止时间、消息与工具调用数)、目录与 git 状态、记忆、技能、全局 `CLAUDE.md` 与 `settings.json`;增量缓存只重读变化文件。
|
|
25
|
+
- 📥 **全保真历史导入** —— 平衡、可继续(resume)的 DSH 会话(`turn/start → step/start → user/message → assistant/message → tool/call → tool/result → step/end → turn/end`),畸形行带行号;中断的工具调用会被修复,保证每个 `tool_use` 恰好对应一个结果(续聊不再永久 400)。
|
|
26
|
+
- 🗂 **单个 `claudecode` 工作区(默认)** —— 每个导入会话都落到专用 "claudecode" 工作区,根目录是新建文件夹(默认 `$DSH_HOME/claudecode`;这是插件唯一会创建的东西)。`workspaceMode: 'per-project'` 可恢复按项目各建工作区的分组方式。
|
|
27
|
+
- 🔁 **复制式 + 增量** —— 两边都不移动、不改写、不删除任何内容;重跑导入只把新增轮次续写进同一 DSH 会话;`force: true` 以新 id 另存一份完整副本。
|
|
28
|
+
- 🧠 **个人上下文持续生效** —— 记忆注入为动态提示词段、Claude 技能注册为真正的 DSH 技能(技能发现会跳过 `README.md` 等非技能文档)、全局 + 项目级 `CLAUDE.md` 前置注入。即便在 `claudecode` 工作区内,也会记住原始项目目录用于记忆/`CLAUDE.md` 解析。
|
|
29
|
+
- ⚡ **与运行中的 Claude Code 实时同步** —— 两个工具并行使用,每次重跑只同步变化部分。
|
|
30
|
+
- 🖥 **Web 面板与一键命令** —— `/claude-import-all`、`/resume-claude` 与带进度的悬浮迁移面板。
|
|
31
|
+
- 🪄 **四合一迁移向导(0.2.1)** —— 一条 `/move` 向导加 `move_detect` / `move_preview` / `move_run` 三个工具,迁移 Claude Code、Codex、OpenCode 与 Hermes:记忆/指令变成带标记的 `AGENTS.md` 管理段,技能变成真正的 DSH 技能,斜杠命令变成 DSH 命令,会话变成可续聊的 DSH 会话——审批门 + 幂等(`move.json`)+ 冲突出 diff 不猜。
|
|
32
|
+
- 🛡 **安全优先** —— 源文件严格只读、DSH 日志 append-only、疑似凭据只报位置、权限类记录只统计不导入。
|
|
33
|
+
|
|
34
|
+
## 🚀 快速开始
|
|
35
|
+
|
|
36
|
+
```sh
|
|
37
|
+
# 1. 安装
|
|
38
|
+
dsh plugin --profile web add -w github:PerryLink/dsh-claude-move
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
2. 在任意 DSH 会话里跑一条命令:
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
/claude-import-all # 扫描 → 复制全部 Claude 会话 → 报告
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
3. 把已打开的 Web 页面刷新一次(面板自带「刷新会话列表」按钮),点开任意已导入会话即可继续。**全程无需重启 DSH**——见[导入之后](#-导入之后)。
|
|
48
|
+
|
|
49
|
+
想要精细控制?
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
claude_scan # 全部项目/会话的结构化索引
|
|
53
|
+
import_claude { path: "~/.claude/projects" } # 单个项目目录(递归)
|
|
54
|
+
import_claude { path: "all" } # 全量
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## 🪄 四合一迁移向导
|
|
58
|
+
|
|
59
|
+
```text
|
|
60
|
+
/move # 一键向导:检测 → 预览 → 执行 → 报告(四源全部)
|
|
61
|
+
move_detect # 扫描 Claude Code / Codex / OpenCode / Hermes
|
|
62
|
+
move_preview # 逐项计划:new | unchanged | changed | conflict(带 diff)| unsupported
|
|
63
|
+
move_run # 审批门后执行;冲突解法:skip | overwrite | rename | merge(默认 skip,绝不猜测)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
- **四源** —— Claude Code(`~/.claude`)、Codex(`~/.codex`)、OpenCode(数据 + 配置根)、Hermes(技能/记忆根);每源独立解析器 + 映射器。
|
|
67
|
+
- **映射** —— 记忆/指令 → DSH 全局 `AGENTS.md` 的只追加管理段(每条一个带标记段);技能 → 真正的 DSH 技能(`SKILL.md` 目录束原样复制,其他格式转换);斜杠命令 → 注册为 DSH 命令(重启后按 `move.json` 重建提示词);会话 → 可续聊 DSH 会话(复用一期导入器)。
|
|
68
|
+
- **幂等** —— 每项已执行计划记录在 `$DSH_HOME/claude-move/move.json`(`digest` / `targetDigest` / `appliedAt`);重跑跳过未变项,`force` 重新应用。
|
|
69
|
+
- **审批门** —— 任何将产生写入的执行先问 `ctx.approval`;非 `allowed-once` 一律零写入。
|
|
70
|
+
|
|
71
|
+
## 🗂 迁移内容对照
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
~/.claude(只读)
|
|
75
|
+
├─ projects/*/*.jsonl ──→ 可续聊的 DSH 会话,归入同一个 "claudecode" 工作区(默认)
|
|
76
|
+
├─ projects/*/memory/ ──→ 动态系统提示词记忆段(每次请求重读)
|
|
77
|
+
├─ skills/** ──→ 真正的 DSH 技能
|
|
78
|
+
└─ CLAUDE.md + settings ──→ 前置提示词段 + 配置建议(绝不代写)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
| Claude Code 里 | 落到 DSH 成为 |
|
|
82
|
+
| --- | --- |
|
|
83
|
+
| 会话 transcript(`projects/*/*.jsonl`) | 平衡、可继续(resume)的 DSH 会话——user/assistant/tool/thinking 全保真映射,含中断工具调用修复——归入同一个 **`claudecode` 工作区**(默认 `$DSH_HOME/claudecode`)或按项目各建工作区(`workspaceMode: 'per-project'`) |
|
|
84
|
+
| 记忆文件(`projects/*/memory/*.md`) | 动态系统提示词上下文段,每次请求重读(`feedback > project > reference > user`)——即便在 `claudecode` 工作区内也记住原始项目目录 |
|
|
85
|
+
| 技能(`~/.claude/skills/**`) | 真正的 DSH 技能(kebab 命名、冲突加后缀、默认上限 30;`README.md`/`MEMORY.md` 与无描述的文件会被跳过) |
|
|
86
|
+
| `CLAUDE.md`(全局 + 项目级) | 前置提示词段;项目级优先 |
|
|
87
|
+
| `settings.json` | DSH 配置建议 + 显式的无法映射键清单 |
|
|
88
|
+
| 项目状态(目录、git 分支与脏行数) | 展示在扫描索引、Web 面板徽标与 `/resume-claude` 交接摘要里 |
|
|
89
|
+
|
|
90
|
+
## 📦 安装
|
|
91
|
+
|
|
92
|
+
```sh
|
|
93
|
+
# 从 GitHub
|
|
94
|
+
dsh plugin --profile web add -w github:PerryLink/dsh-claude-move
|
|
95
|
+
|
|
96
|
+
# 本地源码(开发推荐)
|
|
97
|
+
dsh plugin --profile web add -w link:/path/to/dsh-claude-move
|
|
98
|
+
|
|
99
|
+
# 打包 tarball
|
|
100
|
+
dsh plugin --profile web add -w ./dsh-claude-move-0.1.0.tgz
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
纯 ESM、无构建步骤:git 安装无需 `prepare` 脚本与 `allowBuilds` 白名单。官方打包安装指南见[这里](https://deepseek-harness.github.io/deepseek-harness/develop/basic/publish)。
|
|
104
|
+
|
|
105
|
+
## 🛠 使用
|
|
106
|
+
|
|
107
|
+
在挂载本插件的会话里调用工具:
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
claude_scan # 全量扫描(增量缓存)
|
|
111
|
+
claude_scan { path: "~/.claude/projects/<slug>" } # 局部扫描
|
|
112
|
+
claude_scan { refresh: true } # 忽略缓存全量重扫
|
|
113
|
+
|
|
114
|
+
import_claude { path: "~/.claude/projects/<slug>/<sessionId>.jsonl" } # 单个会话
|
|
115
|
+
import_claude { path: "~/.claude/projects" } # 目录批量(递归)
|
|
116
|
+
import_claude { path: "all" } # 全量批量
|
|
117
|
+
# 可随时重复运行:未变化跳过;源文件增长则只把新轮次续写到同一会话。
|
|
118
|
+
import_claude { path: "...", force: true } # 以 import-<src>-<n> 另存一份完整副本(旧副本保留)
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
命令(用户直接触发,不经模型回合):
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
/claude-import-all # 一键全量:扫描 → 导入 → 报告 → 注入当前会话
|
|
125
|
+
/resume-claude latest # 继续最近的 Claude 会话
|
|
126
|
+
/resume-claude <会话ID> # 按源会话 id 或 import-<src> id
|
|
127
|
+
/resume-claude <关键词> # 匹配标题;多个命中列出候选,绝不猜测
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Web 面板:右下角悬浮「🐳 Claude 迁移」按钮打开面板——项目/会话树(状态徽标:未导入/已导入/源缺失/目录不存在/git 脏)、关键词过滤、单会话「导入并继续」与「刷新会话列表」、批量导入实时进度条。数据走插件自注册的 `/api/claude-move/*` JSON 路由(公开 `ctx.webServer` seam)。
|
|
131
|
+
|
|
132
|
+
- **扫描**返回结构化 JSON 索引:项目(slug/cwd/目录存在性/git 分支与脏行数)、会话(标题/起止时间/消息与工具调用数/畸形行数)、记忆、技能、全局 CLAUDE.md 与 settings.json;每个会话带 `import.status`(`none`/`imported`/`source-missing`);`settingsSuggestions` 是 settings.json 的 DSH 翻译建议与无法映射项(见 [COMPLIANCE.md](COMPLIANCE.md))。
|
|
133
|
+
- **导入**全保真映射 user/assistant/tool/thinking,中断的工具调用会被修复(每个 `tool_use` 恰好一个结果),产物是可继续的平衡会话,默认挂接到 `claudecode` 工作区(或按项目各建工作区);批量逐文件汇总(`imported`/`appended`/`already-imported`/`skipped`/`failed`),畸形行带行号、疑似凭据只报位置(文件:行:类型)、权限类记录只统计不导入。导入绝不删除/改写任何东西:DSH 既有会话原样不动、旧导入副本保留、Claude 源文件从不写入。
|
|
134
|
+
- **个人上下文自动生效(无需导入动作)**:
|
|
135
|
+
- 记忆:全部 `projects/*/memory/*.md` 注入动态上下文段,每次请求按 mtime 重读(新记忆即时生效),`feedback > project > reference > user` 排序,默认 8KB 上限;在 `claudecode` 工作区内,插件会从记录的 `sourceCwd` 解析出原始项目。
|
|
136
|
+
- 技能:`~/.claude/skills/**/SKILL.md`(+ 扁平 `*.md`)注册为 DSH 技能(kebab 归一化、冲突加后缀、上限 30;`README.md`/`MEMORY.md` 与无描述的文件会被跳过,绝不破坏技能加载),catalog 注入与 `skill` 工具由 DSH 负责;
|
|
137
|
+
- 指令:全局 `~/.claude/CLAUDE.md` + 当前会话 cwd 的 `.claude/CLAUDE.md` 注入前置段(项目优先;在 `claudecode` 工作区内经 `sourceCwd` 解析)。
|
|
138
|
+
|
|
139
|
+
## ✅ 导入之后
|
|
140
|
+
|
|
141
|
+
**不需要重启 DSH。** 导入经公开 `sessionPersistence` 服务即时落盘:
|
|
142
|
+
|
|
143
|
+
- 服务端列表(`session.list` / `workspace.list` RPC、CLI、任何新打开的页面)立即可见已导入会话,归入 **`claudecode` 工作区**(`workspaceMode: 'per-project'` 时按项目各建工作区)。
|
|
144
|
+
- 面板会经 shell 官方客户端服务(`sessions.refresh`/`workspaces.refresh`,特性探测)自动刷新已打开页面的会话列表,并为每个会话提供「打开会话」按钮;老 shell 无这些服务时回退「刷新会话列表」按钮 / 整页刷新——导入直接写入持久化服务的 cold 会话,不会发 UI 的 `host/session-added` 实时帧;工作区分组则会实时更新(`host/workspace-changed`)。
|
|
145
|
+
- 导入的会话可立即打开、阅读与续聊——`/resume-claude`,或直接在会话列表中点开。交接摘要会标明原始项目目录。之后随时重跑导入,只会把新增轮次增量续写进同一会话。
|
|
146
|
+
|
|
147
|
+
## ⚙️ 配置(全部可选,可在 cordis.yml 覆盖)
|
|
148
|
+
|
|
149
|
+
```yaml
|
|
150
|
+
- id: claude-move
|
|
151
|
+
name: dsh-claude-move
|
|
152
|
+
config:
|
|
153
|
+
claudeHome: null # 缺省自动定位 $CLAUDE_CONFIG_DIR / ~/.claude
|
|
154
|
+
workspaceMode: claudecode # 'claudecode'(默认:全部导入挂到一个专用工作区)| 'per-project'(按源 cwd 各建工作区)
|
|
155
|
+
claudecodeDir: null # claudecode 工作区目录;默认 $DSH_HOME/claudecode(插件唯一会创建的文件夹)
|
|
156
|
+
scanGit: true # git 探测级别:true 全量 | 'branch' 零 git 子进程 | false 关闭
|
|
157
|
+
gitTimeoutMs: 5000 # git 子进程超时(毫秒)
|
|
158
|
+
scanConcurrency: 8 # 全量扫描的项目并发上限
|
|
159
|
+
maxTranscriptBytes: 67108864
|
|
160
|
+
excludeProjects: [] # slug 子串排除,如 ['demo-']
|
|
161
|
+
enableMemory: true
|
|
162
|
+
memoryMaxBytes: 8192
|
|
163
|
+
memoryScope: current-project # 'current-project' 只注入当前项目 | 'all' 全部、当前项目优先
|
|
164
|
+
enableSkills: true
|
|
165
|
+
maxSkills: 30
|
|
166
|
+
extraSkillDirs: []
|
|
167
|
+
enableInstructions: true
|
|
168
|
+
resumeMaxChars: 2048 # 交接摘要字符上限
|
|
169
|
+
resumeMode: inject # 'inject' 注入交接摘要 | 'agents' 经 ctx.agents.resume 打开会话
|
|
170
|
+
enableWebPanel: true # 注册 /api/claude-move/* 面板路由
|
|
171
|
+
importConcurrency: 4 # 批量导入「读取+转换」并发上限(落盘保持串行)
|
|
172
|
+
# 四合一迁移向导(0.2.1+):
|
|
173
|
+
requireApproval: true # 向导写入先问 ctx.approval(仅 allowed-once)
|
|
174
|
+
codexHome: null # 缺省:$CODEX_HOME 或 ~/.codex
|
|
175
|
+
opencodeDataHome: null # 缺省:平台 XDG 数据目录/opencode
|
|
176
|
+
opencodeConfigHome: null # 缺省:平台 XDG 配置目录/opencode
|
|
177
|
+
hermesHome: null # 缺省:$HERMES_HOME 或 ~/.hermes
|
|
178
|
+
skillsDir: null # 向导技能落点;缺省 $DSH_HOME/skills
|
|
179
|
+
agentsMdPath: null # 向导记忆/指令落点;缺省 $DSH_HOME/AGENTS.md
|
|
180
|
+
moveWorkspaceMode: per-source # 'per-source' | 'single' 向导导入工作区分组
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## 🗑 卸载
|
|
184
|
+
|
|
185
|
+
从 profile 的 bundles 移除 `claude-move` 行并重启 dsh。已导入会话保留在 DSH 数据目录;本插件只在 `$DSH_HOME/claude-move/` 写索引缓存与导入映射、还会写 `claudecode` 工作区文件夹,绝不触碰 Claude 源数据。
|
|
186
|
+
|
|
187
|
+
## 🧭 兼容性
|
|
188
|
+
|
|
189
|
+
- 目标 `dsh 0.1.0-rc.6`(web profile);peer 依赖锁定 rc.6;Node `^22.19 || >=24`。
|
|
190
|
+
- 最后验证 **2026-08-13**(Windows / Node 22,针对 `@deepseek-ai/dsh@0.1.0-rc.6`):tarball 从零安装、真实扫描(40 项目 / 2387 会话)、真实批量导入 13/13 + 幂等重导入 13/13、工作区挂接与持久化产物确认。macOS/Linux 现由 CI 矩阵(linux/macos/windows × Node 22)自动验证。
|
|
191
|
+
- 验证 **2026-08-14**(当前 `deepseek-harness` checkout,web profile / JSONL+zstd 会话后端 / 真实工作区注册表,隔离 DSH_HOME):挂载插件完整启动 web、经面板路由扫描 + 全量导入、创建 `claudecode` 工作区并挂接会话、对既有导入会话增量续写(seq 连续、可正常 load)、重启后幂等重导入,全程既有 DSH 会话不受影响;任何会话都不会被归档、删除或改写。
|
|
192
|
+
|
|
193
|
+
### 兼容矩阵(只依赖公开面)
|
|
194
|
+
|
|
195
|
+
| 面 | 使用 | 缺失时回退 |
|
|
196
|
+
| --- | --- | --- |
|
|
197
|
+
| host 服务(`tools`/`sessionPersistence`/`workspaceRegistry`/`commands`/`systemPrompt`/`skills`/`webServer`) | 按需使用 | 可选服务经 `internal/service` 响应式注册;`fs` 缺失响亮失败 |
|
|
198
|
+
| `sessionPersistence.listSnapshots`/`readFrom`、`fs.streamText`、`ctx.jobs`、`ctx.agents.resume` | 特性探测 | `list()`/整读+响亮拒绝/自有 job 表/交接摘要注入 |
|
|
199
|
+
| 客户端 shell 服务(`sessions.refresh/open`、`workspaces.refresh`) | 面板 apply 时特性探测 | 整页刷新 |
|
|
200
|
+
| 新平台能力一律不是硬依赖——插件在 rc.6 上始终可启动。 | | |
|
|
201
|
+
|
|
202
|
+
## 🔐 权限与数据
|
|
203
|
+
|
|
204
|
+
- **读取** `~/.claude`(transcript、记忆、技能、CLAUDE.md、settings.json)——严格只读——以及导入目标项目目录(`per-project` 模式下工作区挂接)。
|
|
205
|
+
- **写入** 经公开 `sessionPersistence` 服务的 DSH 会话日志——只 `create` + `append`,绝不删除、改写或归档既有会话——工作区注册表记录、插件自有缓存 `$DSH_HOME/claude-move/`(扫描书签 + 导入映射),以及 `claudecode` 工作区文件夹(默认 `$DSH_HOME/claudecode`;仅一次 `mkdir`,绝不删除任何内容)。
|
|
206
|
+
- **绝不** 改写 Claude 源文件、触碰其它应用数据、访问网络。
|
|
207
|
+
- **不读取、不传输任何凭据**;transcript 中的疑似密钥只报告位置。
|
|
208
|
+
|
|
209
|
+
## 🛡 安全边界
|
|
210
|
+
|
|
211
|
+
- 源文件一律只读;DSH 会话日志 append-only(只 `create` + `append`)。
|
|
212
|
+
- 外部 transcript 视为不可信输入:不执行其中任何内容;system/developer/thinking 不进入续聊摘要。
|
|
213
|
+
- 不修改 DSH 引擎、官方 UI 包、apiproxy;只通过公开服务(`sessionPersistence` / `workspaceRegistry` / `tools` / `commands` / `systemPrompt` / `skills` / `webServer`)工作。
|
|
214
|
+
- 疑似密钥/凭据只报位置不展示内容;`permission`/`permission-mode`/`queue-operation` 类记录只统计不导入。
|
|
215
|
+
|
|
216
|
+
## 🩺 排障
|
|
217
|
+
|
|
218
|
+
- 行未生效:`dsh --profile <p> --dump-config` 应显示 `# == dsh-claude-move`;重新执行 `dsh plugin --profile <p> add -w ...`。
|
|
219
|
+
- web 启动后无响应:`dsh plugin add` 初始化的新 profile 只有 `dsh-base`,需在 `dsh.profile.bundles` 补 `@deepseek-ai/dsh-web-app`(装进已有 `web` profile 无需处理)。
|
|
220
|
+
- 面板路由 404:仅当 `enableWebPanel: true` 且组成包含 web 服务器时提供;检查启动日志 FAILED。
|
|
221
|
+
- 导入报「transcript 过大」:调高 `maxTranscriptBytes` 或单独导入该文件。
|
|
222
|
+
- 导入成功但侧边栏看不到新会话:页面在导入前已打开——点一次面板「刷新会话列表」(或刷新页面)即可;**任何时候都不需要重启 dsh**。
|
|
223
|
+
- 日志:启动失败打印在 `dsh` 控制台;插件以 `[claude-move]` 前缀输出工作区/映射错误。
|
|
224
|
+
|
|
225
|
+
## 📚 文档
|
|
226
|
+
|
|
227
|
+
- [PLAN.md](PLAN.md) — 研究结论与实施方案。
|
|
228
|
+
- [ARCHITECTURE.md](ARCHITECTURE.md) — 架构图与完整数据映射表。
|
|
229
|
+
- [COMPLIANCE.md](COMPLIANCE.md) — 对照官方插件约束的逐条审计(deepseek-harness 仓库与文档、[deepseek.com/harness](https://www.deepseek.com/harness/)、[开发者文档](https://deepseek-harness.github.io/deepseek-harness/develop/basic/)、[Cordis](https://github.com/cordiverse/cordis) 与 [Cordis 论文](https://github.com/cordiverse/paper))。
|
|
230
|
+
- [OPTIMIZATION.md](OPTIMIZATION.md) — 实测基线 + 分优先级的优化候选。
|
|
231
|
+
- [RELEASE.md](RELEASE.md) — 发布清单与验收证据。
|
|
232
|
+
- [CHANGELOG.md](CHANGELOG.md) — 各版本变更记录。
|
|
233
|
+
|
|
234
|
+
## 🙏 复用与出处(开源组件)
|
|
235
|
+
|
|
236
|
+
本仓库按 Apache License 2.0 许可;下列 MIT 许可组件保留各自许可证(全文见 [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md)):
|
|
237
|
+
|
|
238
|
+
- 转换核心 vendored 自 [Nwflower/dsh-chat-import](https://github.com/Nwflower/dsh-chat-import)(MIT)。
|
|
239
|
+
- 发现约定与安全模型沿用 [Demogorgon314/dsh-resume-plugin](https://github.com/Demogorgon314/dsh-resume-plugin)(MIT;其 session_reader.py 另有 Apache-2.0 上游出处,见 [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md))。
|
|
240
|
+
- memory/skills 注入与 frontmatter 解析沿用 [YYTbit/dsh-plugin-claude-bridge](https://github.com/YYTbit/dsh-plugin-claude-bridge)(MIT)。
|
|
241
|
+
|
|
242
|
+
## 🧑💻 开发
|
|
243
|
+
|
|
244
|
+
```sh
|
|
245
|
+
npm install # peer 依赖:@deepseek-ai/cordis、@deepseek-ai/dsh-tools@0.1.0-rc.6、@deepseek-ai/schemastery
|
|
246
|
+
npm test # node --test:convert(vendored + 扩展)、discovery、import/report、context、settings
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
CI 经 GitHub Actions([test.yml](.github/workflows/test.yml))在 Node 22 上跑完整套件。
|
|
250
|
+
|
|
251
|
+
## 🧠 Model Experience
|
|
252
|
+
|
|
253
|
+
- 模型可见面 = 两个工具的 description/schema 与输出:`claude_scan` 返回结构化索引,`import_claude` 返回逐文件汇总与告警位置;工具结果本身即落盘的 `tool/result`,全部可重建。
|
|
254
|
+
- 无隐藏模型文本;memory/CLAUDE.md 段注册于 `ctx.systemPrompt`(提示词组装,可随会话日志重建)。
|
|
255
|
+
|
|
256
|
+
## ⚠️ 已知局限
|
|
257
|
+
|
|
258
|
+
- 标题只取 `custom-title`/`ai-title`/首问;Claude `summary` 记录不作为标题。
|
|
259
|
+
- `thinking` 块保留在导入日志的 `reasoning` 内容块中,但不进入续聊摘要。
|
|
260
|
+
- 中断的工具调用会被修复为合成的错误结果(绝不丢弃),因此中途中断的会话仍可续聊——修复会报告为 `repaired.synthesized`。
|
|
261
|
+
- 权限类记录只统计不导入;DSH 权限预设建议随报告生成。
|
|
262
|
+
- Claude `summary` 记录(上下文压缩摘要)只报告、不映射为 DSH compaction 节点——合成压缩事务需伪造 seq 范围与检查点消息,风险大于收益(见 OPTIMIZATION.md);完整历史按原始轮次导入。
|
|
263
|
+
- host 无 `fs.streamText` 流式面时,超过 `maxTranscriptBytes` 的 transcript 响亮失败而非部分导入;有流式面的环境自动走分块流式导入。
|
|
264
|
+
- 在 `workspaceMode: 'per-project'` 下,源目录已删除的会话仍可导入,但工作区挂接失败(留在「未分组」,报告 `workspace.attached: false` 并附 `reason`);默认的 `claudecode` 工作区不依赖源目录,因此此类会话在其中正常挂接。
|
|
265
|
+
- 批量导入中断可安全重跑(幂等、append-only):已完成文件跳过、已增长文件只续写新轮次。
|
|
266
|
+
- 若源文件被原地重置/截断(轮次少于已导入记录),重导跳过并报 `sourceShrunk`;需要完整副本用 `force: true`。
|
|
267
|
+
- Web 面板为零构建悬浮面板,走插件自注册 JSON 路由;不使用 shell 内部 UI slot(刻意不依赖 rc.6 未文档化内部面)。
|
|
268
|
+
- 流式增量续写时,单次结果的 `messages`/`toolCalls` 只统计本次新增事件(已存储前缀不重读);`turns` 仍为全量轮次。
|
|
269
|
+
|
|
270
|
+
## 🤝 参与贡献与反馈
|
|
271
|
+
|
|
272
|
+
欢迎提 Issue 与 PR——请使用对应模板([缺陷报告](.github/ISSUE_TEMPLATE/bug-report.yml)、[功能请求](.github/ISSUE_TEMPLATE/feature-request.yml))。问题与讨论在仓库的 [GitHub Discussions](https://github.com/PerryLink/dsh-claude-move/discussions)。安全问题请通过 GitHub Security Advisories(仓库 Settings → Security)私下报告,详见 [SECURITY.md](SECURITY.md)。
|
|
273
|
+
|
|
274
|
+
## 💛 贡献者致谢
|
|
275
|
+
|
|
276
|
+
感谢每一位让这个插件变得更好的人:
|
|
277
|
+
|
|
278
|
+
- [OLDnana1](https://github.com/OLDnana1) —— 定位了「中断工具调用」导致导入会话续聊永久 400 的根因([#1](https://github.com/PerryLink/dsh-claude-move/issues/1)),已于 v0.2.0 修复。
|
|
279
|
+
- [GooodWei](https://github.com/GooodWei) —— 发现 `README.md`(及任何无描述的 `.md`)被误注册为技能、导致 DSH 技能加载整体失败([#1](https://github.com/PerryLink/dsh-claude-move/issues/1)),已于 v0.2.0 修复。
|
|
280
|
+
- 本插件所复用的 MIT 上游项目在[署名](#-attribution-open-source-components)与 [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md) 中致谢。
|
|
281
|
+
|
|
282
|
+
## 🔗 相关链接
|
|
283
|
+
|
|
284
|
+
- DeepSeek Harness:[仓库](https://github.com/deepseek-ai/deepseek-harness) · [官网](https://www.deepseek.com/harness/) · [开发者文档](https://deepseek-harness.github.io/deepseek-harness/develop/basic/)
|
|
285
|
+
- 插件生态:[`dsh` topic](https://github.com/topics/dsh) · [`dsh-plugin` topic](https://github.com/topics/dsh-plugin) · [Discord](https://discord.gg/Ycq5dCaS4)
|
|
286
|
+
|
|
287
|
+
## 📄 License
|
|
288
|
+
|
|
289
|
+
Apache License 2.0 — 见 [LICENSE](LICENSE) 与 [NOTICE](NOTICE)。第三方声明(含 MIT 组件的 MIT 原文)见 [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md)。
|
|
290
|
+
|
|
291
|
+
## PerryLink DSH 插件家族
|
|
292
|
+
|
|
293
|
+
本项目是 [PerryLink](https://github.com/PerryLink) 维护的 [15 个 DeepSeek Harness 插件](https://github.com/PerryLink)之一。如果你觉得这个插件有用,其余的很可能同样有用:
|
|
294
|
+
|
|
295
|
+
| 插件 | 一句话说明 |
|
|
296
|
+
|---|---|
|
|
297
|
+
| [dsh-mcp-panel](https://github.com/PerryLink/dsh-mcp-panel) | 只读 MCP 运行时面板:/mcp 命令 + 设置页,状态/工具/错误一览 |
|
|
298
|
+
| [dsh-doublecheck](https://github.com/PerryLink/dsh-doublecheck) | 工程纪律守门:需求审讯、测试证据门、对抗评审 |
|
|
299
|
+
| [dsh-background-agents](https://github.com/PerryLink/dsh-background-agents) | 持久化后台子代理:Web 侧边栏进度、随时留言与打断 |
|
|
300
|
+
| [dsh-lsp-actions](https://github.com/PerryLink/dsh-lsp-actions) | 基于语言服务器的诊断/格式化/补全/代码动作/重命名 |
|
|
301
|
+
| [dsh-output-styles](https://github.com/PerryLink/dsh-output-styles) | 对标 Claude Code outputStyles 的运行时风格切换 |
|
|
302
|
+
| [dsh-checkpoint-rewind](https://github.com/PerryLink/dsh-checkpoint-rewind) | 对标 Claude Code /rewind:快照、会话 fork、一键回退 |
|
|
303
|
+
| [dsh-permission-rules](https://github.com/PerryLink/dsh-permission-rules) | Claude Code 风格声明式 allow/deny/ask 权限规则,带审计 |
|
|
304
|
+
| [dsh-auto-review](https://github.com/PerryLink/dsh-auto-review) | 审批链上的第二模型自动审查,默认 fail-closed |
|
|
305
|
+
| [dsh-memento](https://github.com/PerryLink/dsh-memento) | 带审批门的跨会话记忆:ctx.memory + SQLite + memory 工具 |
|
|
306
|
+
| [dsh-skill-pack-security](https://github.com/PerryLink/dsh-skill-pack-security) | 安全审计技能包:密钥扫描、依赖与供应链审查 |
|
|
307
|
+
| [dsh-session-pin](https://github.com/PerryLink/dsh-session-pin) | 在 Web 侧边栏置顶会话,持久排序 |
|
|
308
|
+
| [dsh-composer-history](https://github.com/PerryLink/dsh-composer-history) | Web 作曲器终端式输入历史:方向键、Ctrl+R 搜索 |
|
|
309
|
+
| [dsh-github](https://github.com/PerryLink/dsh-github) | DSH 的 GitHub PR/issue 集成,所有写操作经审批门 |
|
|
310
|
+
| [dsh-plugin-guide](https://github.com/PerryLink/dsh-plugin-guide) | 插件开发知识库,随 bundle 安装的按需 agent 技能 |
|
|
311
|
+
| **[dsh-claude-move](https://github.com/PerryLink/dsh-claude-move)** | 把 Claude Code 会话、记忆、技能和 CLAUDE.md 迁入 DSH |
|