PerryLink/dsh-checkpoint-rewind
PerryLink/dsh-checkpoint-rewind has 30 GitHub stars and 4 forks. GitHot measured 0 stars in 24 hours and 0 in 7 days. Last checked 2026-11-14 21:04 UTC. Last push 2026-11-04.
Crecimiento de estrellas medido
- in 24h
- 0
- in 7 days
- 0
- in 15 days
- Recopilando historial
- in 1 month
- Recopilando historial
Cambios netos en períodos que se solapan, no totales diarios. Los datos no disponibles se dejan en blanco. Las estrellas indican interés, no calidad.
Acerca de
Claude Code /rewind for DeepSeek Harness — git-first workspace snapshots before every mutation, turn-boundary session forks, one-shot /rewind restore. A dsh-plugin capability seam.
Herramientas de desarrolloREADME-es.md
Original⏪ dsh-checkpoint-rewind
- Canal 1024 store:
npm i -g dsh1024una vez, luegodsh1024 plugin --profile web add dsh-checkpoint-rewind(cuenta para el ranking de instalaciones de deepseek1024.com).
Checkpoints unificados de DeepSeek Harness: instantáneas de tres estados — sesión + workspace + configuración — con reversión de un solo paso.
El equivalente a los Checkpoints de Claude Code, construido como plugin de costura de capacidad (capability-seam): captura antes de cada mutación y restaura cualquiera de los tres estados con un único comando aprobado.
English · 简体中文 · Español · Português · हिन्दी
dsh plugin --profile <name> add dsh-checkpoint-rewind
📖 Base de conocimiento del ecosistema — datos medidos, no marketing: guía de desarrollo · datos de selección · criterios de mantenimiento.
Instalación y desinstalación
- Canal git (último
main):dsh plugin --profile web add github:PerryLink/dsh-checkpoint-rewind— ESM puro, sin paso deprepareniallowBuilds. - Canal npm (versiones publicadas):
dsh plugin --profile web add dsh-checkpoint-rewind. - Canal tarball:
npm packen este repo y luegodsh plugin --profile web add ./dsh-checkpoint-rewind-<version>.tgz. - Pila de almacenamiento (necesaria para los checkpoints, opcional para montar):
@deepseek-ai/dsh-storage+@deepseek-ai/dsh-storage-json(configroot) +@deepseek-ai/dsh-storage-domain(configbackend: json) — ver Inicio rápido; el plugin se monta igualmente sin ella y cada comando explica la solución. - Desinstalación:
dsh plugin --profile web remove dsh-checkpoint-rewind— los archivos de instantánea permanecen hasta que borres$DSH_HOME/dsh-checkpoint-rewind; los objetos git se recogen con el recolector de basura.
⭐ 如果它帮到了你
Este plugin forma parte de la familia de plugins DSH (más de 40, todos Apache-2.0). Si te resulta útil, dale una estrella: no desbloquea nada, pero ayuda a que la siguiente persona lo encuentre antes.
English: part of a 95 plugin family for DeepSeek Harness. If it is useful, a star helps the next person find it — nothing is gated behind it.
What is dsh-checkpoint-rewind?
Checkpoints unificados de DeepSeek Harness: instantáneas de tres estados — sesión + workspace + configuración — con reversión de un solo paso.
El equivalente a los Checkpoints de Claude Code, construido como plugin de costura de capacidad (capability-seam): captura antes de cada mutación y restaura cualquiera de los tres estados con un único comando aprobado.
Resumen del flujo: instalar → abrir panel → actuar. Los ejemplos siguientes usan la superficie de comandos real.
La misma ejecución, animada.
Comparison

Capabilities out of 2 (restores files? / rewinds the session?) · counted from the README comparison table
Compatibilidad
| Superficie | Estado |
|---|---|
| Harness | DeepSeek Harness dsh-v0.2.1-alpha.1 (tag de GitHub, verificado el 2026-09-25; pin npm 0.1.7-rc.2, peers `>=0.1.6-0 <0.2.0 |
| Node | ^22.19.0 || >=24.0.0 |
| Plataformas | Todas (comandos + listeners de host; línea de tiempo de Ajustes opcional mediante la capacidad settings) |
| Modelo | Cualquiera (sin llamadas al modelo — las instantáneas y restauraciones son deterministas) |
Qué obtienes
dsh-checkpoint-rewind captura un checkpoint unificado de tres estados — workspace, cursor de sesión y configuración del plugin — y restaura uno o los tres con un único comando aprobado:
- Registro de tres estados — cada checkpoint guarda el estado del workspace (SHA del árbol git, o un manifiesto de copia), el cursor de eventos de la sesión (
seq+ límite de turno) y una instantánea de configuración, etiquetado por origen (manual/auto/guard/mutation). - Cuatro disparadores de captura — antes de cada herramienta de mutación (
fs/write-intent,fs/edit-intent,tools/pre-execute), en el intervalo automático (autoCheckpoint, por defecto cada paso), manualmente (/checkpointy la herramientacheckpoint), y como guardia antes de cada reversión. - Proveedor git primero —
git stash create/commit-treeproducen objetos de instantánea no referenciados que nunca tocan tu worktree, índice o historial; la restauración es solo-worktree y por rutas explícitas. Los directorios no git (y los repos con HEAD no nacido) degradan a un proveedorcopyincremental con reutilización de hardlinks. - Reversión de un solo paso —
/rewind workspace|session|config|all <target>restaura los estados seleccionados;previewes un informe de impacto de solo lectura,diff <a> <b>compara dos checkpoints,clearlos elimina (esta sesión;clear --allabarca todas las sesiones y workspaces). - Reversión de sesión por fork — la reversión de sesión reproduce eventos hasta el límite del checkpoint mediante la primitiva oficial
SessionStore.fork, creando una nueva sesión hija (con respaldo a la rutasessions.createcon semilla cuando el host no tiene fork o el checkpoint no tiene límite); la sesión original conserva su historial completo. - Línea de tiempo en Ajustes — la pestaña
Plugins → Checkpointsmuestra los checkpoints de la sesión con diffs línea a línea entre pares.
¿Por qué otro plugin de rewind?
| Plugin | Qué vende | ¿Restaura archivos? | ¿Rebobina la sesión? |
|---|---|---|---|
| dsh-checkpoint-rewind (este) | instantáneas de objetos git + reversión de tres estados + restauración de un solo paso | ✅ estado completo del workspace | ✅ sesión hija por reproducción de semilla |
| Anionex/dsh-turn-rewind | Change Ledger persistente de deltas por mutación | ✅ reproduciendo deltas inversos | ✅ su propio modelo de ledger |
| LingLambda/dsh-undo | reversión pura de contexto al último paso completado | ❌ | ✅ solo contexto |
| Mongfayi/dsh-recall | recall de mensajes (elimina un turno y todo lo posterior) | ❌ (explícitamente) | ✅ eliminación de turno |
La diferencia en una frase: dsh-checkpoint-rewind captura el estado del workspace con primitivas git sin efectos secundarios antes de cada mutación, y convierte “volver al paso N” en un único comando aprobado — primero el checkpoint de guardia, segundo los archivos restaurados, tercero la configuración restaurada, cuarto la sesión reproducida, cada fase registrada. Sin contabilidad de deltas que pueda derivar, sin edición a nivel de mensaje (eso pertenece a otro plugin), sin sincronización entre dispositivos.
Inicio rápido
dsh plugin --profile web add github:PerryLink/dsh-checkpoint-rewind
# 1. instala el bundle en tu perfil
dsh plugin --profile web add github:PerryLink/dsh-checkpoint-rewind
# o desde npm (versiones publicadas)
dsh plugin --profile web add dsh-checkpoint-rewind
# 2. reinicia y verifica la fila
dsh --profile web --dump-config | grep -A4 'id: checkpoint-rewind'
Los checkpoints persisten a través del servicio storageDomain. El plugin se monta sin él y nunca bloquea el arranque del perfil — los comandos checkpoint/rewind devuelven entonces un error estructurado indicando las filas exactas que hay que añadir. Compón la pila de almacenamiento una vez para habilitarlos:
- insert:
- id: checkpoint-rewind-storage
name: '@deepseek-ai/dsh-storage'
- id: checkpoint-rewind-storage-json
name: '@deepseek-ai/dsh-storage-json'
config:
root: !!js dshHomePath('checkpoint-rewind/storage')
- id: checkpoint-rewind-storage-domain
name: '@deepseek-ai/dsh-storage-domain'
config:
backend: json
El paquete es ESM puro sin paso de build — index.mjs y lib/ son los artefactos enviados. Las mutaciones del workspace ahora crean checkpoints automáticamente; ejecuta /rewind para listarlos (o /rewind list brief para entradas de una línea con el número de sesión):
rewind: 3 checkpoints (newest last):
#a1b2c3d4 · (git) · turn 2 step 1 · 2026-08-14 12:00:01 (3 min ago) · trigger: bash · 4 files · 1.2 MiB
#b2c3d4e5 · (git) · turn 2 step 3 · 2026-08-14 12:00:41 · trigger: str_replace_editor · 2 files · 310 KiB
#c3d4e5f6 · (copy) · turn 3 step 1 · 2026-08-14 12:01:10 · trigger: write · 1 file · 90 KiB
run "/rewind <id>" to restore files and fork the session from that checkpoint
Dirígete a un checkpoint por su número de sesión (el número corto y acotado que muestra /rewind list brief), por prefijo de id único, por número de paso o por latest:
/rewind list brief # una línea por checkpoint, numerada, la más reciente primero
/rewind 3 # el checkpoint número 3 de ESTA sesión (acierto exacto, nunca difuso)
/rewind preview 3 # solo lectura: muestra qué archivos cambiarían, no toca nada
/rewind b2c3d4e5 # el prefijo de id único (el id de 8 caracteres) sigue funcionando igual
/rewind step 2
/rewind latest
/rewind workspace 3 --files src/a.ts,src/b.ts # restauración selectiva: solo estos archivos (con aprobación)
/rewind clear # eliminación confirmada de los checkpoints de esta sesión (archivos intactos)
/rewind clear --all # eliminación confirmada en TODAS las sesiones y workspaces (archivos intactos)
Números de sesión (ids cortos acotados)
- Cada checkpoint recibe un número al crearse, empezando en
1./rewind 3resuelve ese número exactamente: los dígitos nunca se tratan como prefijo de id, así que/rewind 3no puede caer en el checkpoint cuyo UUID empieza por3. - Alcance: por sesión (
sessionId). Cada sesión numera sus propios checkpoints; un número es único dentro de su sesión, y/rewind <número>solo resuelve contra los checkpoints de la sesión (y workspace) actual. - Monótono y nunca reutilizado. La poda por cuota (
maxSnapshots) y/rewind clear//rewind clear --allborran registros pero nunca liberan un número: tras un clear el siguiente checkpoint continúa desde la marca alta anterior (después de#1 #2 #3y unclear, el siguiente es#4, no#1). El número se guarda en el propio registro y el contador vive en el slot global del dominio, así que borrar registros no puede reiniciarlo. - Los checkpoints antiguos se numeran al primer contacto. Los registros escritos antes de esta función (sin campo de número) se numeran en orden de creación la primera vez que la sesión se lista o se revierte, y esa numeración se persiste; los nuevos continúan después. Nada se salta ni se reasigna, y el direccionamiento por prefijo de id sigue funcionando para ellos.
/rewind list(la lista detallada) no cambia: sigue imprimiendo el id de 8 caracteres por línea y su última línea remite a/rewind list briefpara los números.
preview se resuelve con el mismo direccionamiento e imprime el impacto sin pedir confirmación ni escribir nada.
Ejemplos
Son los puntos de entrada reales; instala y llama a uno.
Ejemplo detallado
Comando
/rewind preview cp-9
Salida
rewind preview: checkpoint #cp-9 (provider git, turn 2 step 3)
restoring it would overwrite 2 file(s):
a.txt
b.txt
5 file(s) already match the checkpoint (not touched).
no files are deleted: 1 file(s) created after the checkpoint would be left in place:
new.txt
run "/rewind <id>" to confirm and apply (a guard checkpoint is captured first)
Observado en test/checkpoints.test.mjs:289-301; lib/checkpoints.mjs:484-500
Rama de fallo
Entrada
/rewind nope
Salida
rewind: unknown checkpoint id "nope" (run /rewind to list)
Observado en plugins/dsh-checkpoint-rewind/lib/errors.mjs:72; plugins/dsh-checkpoint-rewind/index.mjs:1223; plugins/dsh-checkpoint-rewind/test/index.test.mjs:346-350
Ejemplos breves
/checkpoint/rewind preview
Configuración
Todas las opciones son campos Schemastery Config (modificables desde cordis.yml). Nada está hardcodeado. Las opciones de proveedor (gitBin, snapshotDir, excludeGlobs, verifyByHash) se leen de la configuración viva en el momento de uso, de modo que los cambios en cordis.yml se aplican sin reiniciar.
| Clave | Por defecto | Significado |
|---|---|---|
enabled |
true |
Interruptor maestro; en false, elimina comandos, listeners y proveedores por completo |
provider |
auto |
Proveedor de instantáneas: auto (git si está disponible, si no copy) · git · copy |
gitBin |
git |
Ruta del ejecutable de git |
snapshotDir |
$DSH_HOME/dsh-checkpoint-rewind (repliegue ~/.dsh/dsh-checkpoint-rewind si $DSH_HOME no está definido) |
Raíz de las instantáneas del proveedor copy |
maxSnapshots |
50 |
Checkpoints conservados por sesión (los más antiguos se podan primero) |
maxSnapshotBytes |
536870912 (512 MiB) |
Cuota blanda global de bytes incrementales (siempre se conserva el más nuevo por sesión viva) |
pruneOnTurnEnd |
true |
Ejecuta la poda de cuota al terminar un turno |
mutationTools |
['bash','write','edit','str_replace_editor','pwsh','terminal_send'] |
Herramientas tratadas como mutantes en tools/pre-execute |
excludeGlobs |
['node_modules','.git','.dsh','dist','build'] |
Patrones glob omitidos por el proveedor copy |
confirmVia |
auto |
Canal de confirmación: auto (userQuestions primero) · userQuestions · approval |
listLimit |
10 |
Checkpoints mostrados por /rewind sin argumentos |
preRewindCheckpoint |
warn |
Checkpoint de guardia antes de restaurar: warn · require · off |
verifyByHash |
false |
Comparación por hash de contenido y verificación de restauración del proveedor copy |
autoCheckpoint.enabled |
true |
Instantáneas automáticas por intervalo en step/start |
autoCheckpoint.intervalMinutes |
0 |
Intervalo; 0 = cada paso |
workspaceRestore |
restore |
Reversión del workspace: restore (sobrescritura segura) · reset-hard (estilo CC, opt-in) |
diffRenderer |
pairwise |
Renderizador de diff de la página de ajustes: pairwise (texto línea a línea) · side-by-side (dos columnas por archivo) |
selectiveRestore |
true |
Restauración selectiva por archivo (/rewind … --files) y la casilla por archivo del panel + total de tamaño |
promptSection |
true |
Inyecta una sección breve de rol en el prompt |
checkpointTool |
true |
Registra la herramienta de modelo checkpoint |
- insert:
- id: checkpoint-rewind
name: dsh-checkpoint-rewind
config:
provider: auto
maxSnapshots: 50
maxSnapshotBytes: 536870912
pruneOnTurnEnd: true
confirmVia: auto
preRewindCheckpoint: warn
Herramientas y superficies
| Superficie | Tipo | Notas |
|---|---|---|
/rewind |
comando | [workspace|session|config|all] <number|id-prefix|step <N>|latest> · list [brief] · diff <a> <b> · preview <target> · clear [--all] |
/checkpoint |
comando | [note <text>|list|diff <a> <b>] — captura un checkpoint manual |
checkpoint |
herramienta | Captura un checkpoint manual con nota opcional |
fs/write-intent · fs/edit-intent · tools/pre-execute |
listeners | Captura pre-mutación (prepend pass-through; nunca roba el hueco de política) |
session/event |
listener | Seguimiento de turno/paso, intervalo automático, relleno de límites, poda al fin de turno |
Proyección checkpoints |
proyección de sesión | Franja de línea de tiempo plegada desde el log de sesión |
| Línea de tiempo de Ajustes | cliente | Pestaña Plugins → Checkpoints con diffs entre pares |
Modelo de seguridad
- El historial de git es intocable. El proveedor git solo ejecuta primitivas sin efectos secundarios de la lista blanca —
stash create,commit-tree,restore --worktree,ls-tree,diff-tree,ls-files,status,rev-parse,cat-file -e— impuestas por una aserción en tiempo de ejecución, y las referencias de objetos se validan como ids hexadecimales antes de pasarlas a git (un registro manipulado no puede inyectar opciones de git). Nuncareset --hardpor defecto, nuncaclean, nunca mutación de índice/historial (verworkspaceRestoreabajo). - Reversión por sobrescritura, nunca borrado. La restauración solo sobrescribe archivos capturados, y el proveedor git restaura rutas explícitas (
git restore … -- .borraría archivos añadidos congit adddespués del checkpoint). Los archivos creados después del checkpoint (no rastreados o staged) se informan y se dejan en su sitio. - Sin escrituras a través de enlaces, sin path traversal. El proveedor copy valida las referencias de checkpoint antes de unirlas a las rutas del directorio de instantáneas, y se niega a restaurar a través de un destino (o ancestro) que se haya convertido en un enlace simbólico — así una restauración nunca puede seguir un enlace fuera del workspace.
- La restauración requiere aprobación. Sobrescribir archivos del usuario siempre pasa por la costura de confirmación con semántica
ask; un answerer ausente, que lanza error o que responde “no” cierra en fallo./rewind previewes la forma de solo lectura de inspeccionar el impacto primero. - La reversión es reversible. Antes de restaurar, un checkpoint de guardia captura el estado actual; restaurar la guardia deshace la reversión.
preRewindCheckpoint: requireaborta la reversión cuando la guardia no puede capturarse. - Transacción de orden fijo. Primero la guardia, segundo el workspace, tercero la configuración, cuarto la reproducción de la sesión; cada fase se registra; una restauración fallida deja archivos, checkpoints y sesión intactos.
workspaceRestore: 'reset-hard'equivale a CC y es opt-in. Ejecutagit reset --hard <snapshot commit>(la cabeza de la rama se mueve al commit de la instantánea; el historial previo a la instantánea sigue siendo recuperable vía reflog; los archivos no rastreados no se tocan). Está desactivado por defecto.- Visible para el modelo ⟺ registrado. Todo lo que un usuario o modelo ve se reconstruye a partir de
command/run+command/done(y, una vez que el host los conoce, los eventoscheckpoint/*) más el dominio durablecheckpoints.
Cómo funciona
capture ── fs/write-intent · fs/edit-intent · tools/pre-execute (prepend, pass-through)
── step/start auto interval ── /checkpoint · checkpoint tool ── pre-rewind guard
│
▼ ProviderRegistry.resolve(auto) → git: stash create / commit-tree
│ copy: incremental dir + hardlinks
▼
checkpoints storage domain (SQLite rows / JSON file) + checkpoint/* event (adaptive gate)
/rewind <target> ── confirm (userQuestions / approval, fail-closed) ──▶ guard checkpoint
├─ workspace: provider.restore(ref) (restore | reset-hard)
├─ config: settings write-back (persisted on the profile patch)
└─ session: SessionStore.fork(source, boundary) → new child session (original untouched)
Registro de decisiones completo, vocabulario de eventos y contrato de la costura de proveedores: ARCHITECTURE.md.
Eventos de sesión (nota rc.2)
El plugin declara checkpoint/snapshot, checkpoint/bound, checkpoint/prune y checkpoint/rewind como miembros SessionEventMap solo de log. El harness rc.2 no tiene superficie de registro de eventos para plugins y Session.append descarta silenciosamente las claves de opciones desconocidas, por lo que añadir tipos desconocidos haría la sesión ilegible al recargarla. Por eso el plugin añade a través de una puerta adaptativa: una sonda en tiempo de ejecución (sobre un almacén de sesión separado, nunca persistido) detecta si el append del host sella el sobre ignorable — en rc.2 la puerta permanece cerrada; en hosts que lo soportan, los eventos checkpoint/* se añaden automáticamente con ignorable: true. Hasta entonces, la cadena de auditoría autoritativa es command/run + command/done (conocidos por el harness) más el dominio de almacenamiento durable checkpoints.
Ancla de Web UI
El plugin devuelve el id de la nueva sesión en el resultado del comando (session: <id>) y el shell web puede navegar allí. La unidad de proyección de sesión checkpoints viene incluida: siempre que ctx.sessionProjections exista, el plugin registra la unidad vía ctx.inject (pliega checkpoint/snapshot|bound|prune|rewind en una lista de valor completo) — permanece como lista vacía en hosts rc.2 hasta que una build del harness incluya el vocabulario checkpoint/* o el sobre ignorable, y entonces se llena sin cambios en el plugin.
FAQ
¿Esto reemplaza a git? No — lo usa donde está disponible. En un repo git obtienes objetos de instantánea exactos al byte, deduplicados, sin tocar el historial; en cualquier otro directorio, el proveedor copy hace lo mismo con archivos normales. Los commits regulares siguen siendo tu historial a largo plazo.
¿Por qué no usar git reset --hard por defecto? Porque destruir estado no es el trabajo de una red de seguridad. El plugin solo crea objetos no referenciados y realiza restauraciones exclusivas del árbol de trabajo y explícitas por ruta por defecto, de modo que un retroceso defectuoso nunca pueda perder el historial, el índice o los archivos creados después del checkpoint. reset-hard está disponible detrás de workspaceRestore: 'reset-hard' para usuarios que desean explícitamente paridad con CC.
¿Cuánto tiempo es restaurable un checkpoint? No se mantiene ninguna referencia para los snapshots de git-provider. Son objetos no referenciados de stash create/commit-tree por diseño, y discard solo elimina el registro de metadatos, dejando el objeto para git gc. Dos límites independientes definen la ventana de restauración real: la cuota del plugin (maxSnapshots por defecto 50 por sesión; maxSnapshotBytes 512 MiB de cuota blanda global aplicada mediante pruneAll() en cada captura y limpiada al final de turnos) y el git gc del repositorio host (gc.pruneExpire por defecto 2 semanas). Un git gc --prune=now manual, repack agresivo o clon fresco los elimina inmediatamente. Los objetos purgados ahora se detectan por adelantado: el proveedor git sondea el objeto de instantánea antes de restaurar (git cat-file -e) y falla en voz alta si falta, en lugar de no restaurar nada, y un paso doctor recorre cada registro de checkpoint para sondear la existencia del objeto y marcar los no restaurables ([UNRESTORABLE: object missing] en la lista). El paso doctor está implementado y probado, pero aún no está conectado a la ruta de restauración (restore aún no consulta la marca unrestorable; seguimiento en discussion #13).
¿Puedo retroceder a un paso en medio de un turno? La restauración de archivos es precisa por pasos (/rewind step <N> = snapshot más cercano ≤ N). La reproducción de la sesión, sin embargo, respeta la granularidad de reproducción del harness: la sesión hija se inicializa hasta el límite del turno del checkpoint.
¿Qué pasa si nadie puede responder a la confirmación? No se toca nada — el plugin cierra en fallo (unavailable/rejected), conserva el checkpoint y devuelve un error explicativo. Con confirmVia: approval en rc.2 el mensaje dice que montes userQuestions, porque approval requiere un turno abierto y los comandos se ejecutan entre turnos.
¿Puedo deshacer una reversión? Sí — cada reversión aprobada captura primero un checkpoint de guardia del estado previo a la reversión; el resultado imprime rewind guard: <id>, y /rewind <guard-id> restaura ese estado.
¿Cómo direcciono los checkpoints? Con el número de sesión (/rewind 3 — ver /rewind list brief; por sesión, monótono, nunca reutilizado), el prefijo de id único (el id de 8 caracteres de la lista sigue funcionando), /rewind step <N> y /rewind latest. /rewind clear borra los checkpoints de esta sesión y /rewind clear --all los borra en todas las sesiones y workspaces (archivos intactos) — ninguno reinicia la numeración. /rewind preview <target> usa el mismo direccionamiento para mostrar el impacto sin cambiar nada.
¿Por qué el número sigue subiendo después de un clear? Porque un número es una dirección, no una posición: reutilizar #1 para otro checkpoint tras un clear redirigiría en silencio todo lo que mencionara #1. El contador se persiste en el slot global del dominio checkpoints y cada registro guarda su propio número, así que podar y limpiar borran instantáneas sin reciclar ids.
¿Qué hace preview — y qué no hace? Resuelve el checkpoint y ejecuta una comparación de solo lectura: qué archivos se sobrescribirían (o recrearían), cuáles ya coinciden y qué archivos creados después del checkpoint se dejarían en su sitio. Nunca pregunta, nunca escribe, nunca bifurca y no registra ningún evento checkpoint/rewind — la puerta de aprobación solo se ejecuta en un /rewind <id> real.
Demo
Una ejecución real de integración headless ensamblada (npm run test:integration) recorre el flujo completo: el agente modifica archivos a lo largo de dos turnos, luego /rewind preview inspecciona el impacto en modo solo lectura (sin puerta de confirmación, sin escrituras) y /rewind <id> restaura los archivos y reproduce la sesión en una nueva sesión hija. La ejecución verifica el contenido de los archivos, el contexto del hijo reproducido, el checkpoint de guardia y la supervivencia de los archivos creados después del checkpoint — para los flujos de proveedor copy y git (el flujo git también verifica que HEAD y el reflog quedan intactos). El controlador vive en test/integration/rewind-headless.mjs.
Permisos y datos
- Permisos: el manifiesto del workshop declara
workspace:read,workspace:write,git:read,git:write,snapshot-storage:write,session-log:read,settings:writeynetwork:none. - Datos: los registros de checkpoint viven en el dominio de almacenamiento
checkpoints(filas SQLite o un archivo JSON); las instantáneas de copia viven bajosnapshotDir. El slot global del dominio guarda los contadores de números cortos por sesión, por lo que borrar registros (prune,clear,clear --all) nunca puede reciclar un número. Totalmente local — sin red, sin credenciales. El dominio se abre en doble versión: los medios de la era 0.4.x (dominio v1) se abren en modo de compatibilidad que mantiene legibles los registros antiguos y guarda las nuevas capturas con la forma v2, de modo que actualizar el plugin nunca deja huérfano un medio existente. - Registro de sesión: los eventos
checkpoint/*se añaden mediante la puerta adaptativa; la cadena de auditoría autoritativa escommand/run+command/donemás el dominio durable.
Límites de seguridad
- El historial de git es intocable. Primitivas sin efectos secundarios de la lista blanca;
reset --hardsolo detrás del modo opt-inworkspaceRestore: 'reset-hard'. Nuncagit clean. - Reversión por sobrescritura, nunca borrado. La restauración sobrescribe solo archivos capturados; los archivos creados después del checkpoint se informan y se dejan en su sitio.
- Sin escrituras a través de enlaces, sin path traversal. Los
refde copy se validan como ids de instantánea; la restauración se niega a seguir enlaces simbólicos fuera del workspace. - La restauración requiere aprobación. Un answerer ausente o que niega cierra en fallo.
- La reversión es reversible. Primero se captura un checkpoint de guardia del estado previo a la reversión.
Limitaciones conocidas
- En rc.2, los eventos de sesión
checkpoint/*son suprimidos por la puerta adaptativa; la cadena de auditoría usacommand/run+command/donemás el dominio de almacenamiento hasta que un host incluya el vocabulario o el sobreignorable. confirmVia: approvalnecesita un turno abierto, y los comandos se ejecutan entre turnos — monta userQuestions (o defineconfirmVia: userQuestions) en rc.2.- La reversión de sesión bifurca (fork) una nueva sesión hija en el límite del checkpoint; nunca reescribe ni trunca la sesión original.
workspaceRestore: 'reset-hard'mueve la cabeza de la rama al commit de la instantánea; está desactivado por defecto.- Un checkpoint capturado antes de cualquier turno cerrado no tiene límite de reproducción — la reversión de sesión crea entonces una sesión hija nueva con contexto vacío.
Solución de problemas
| Síntoma | Causa / solución |
|---|---|
/rewind <id> dice rewind cancelled: no confirmation answerer |
No hay ningún canal userQuestions/approval montado — el plugin cierra en fallo. Ejecútalo en la Web UI (o monta un proveedor de preguntas); confirmVia selecciona el canal. |
/rewind <id> dice approval requires an open turn … |
Los comandos se ejecutan entre turnos y approval necesita un turno — monta userQuestions o define confirmVia: userQuestions. |
rewind: checkpoint registry unavailable |
El dominio de almacenamiento checkpoints no pudo abrirse. O el servicio storageDomain no está compuesto (añade las filas de la pila de almacenamiento de Inicio rápido: @deepseek-ai/dsh-storage + @deepseek-ai/dsh-storage-json con config root + @deepseek-ai/dsh-storage-domain con config backend: json) o el backend tiene errores; revisa los logs del harness. |
Un checkpoint aparece como fork: pending (turn not closed) |
Su turno aún no tiene turn/end; los archivos aún pueden restaurarse, pero la reproducción de la sesión espera a que el turno se cierre. |
files restored … but the session was NOT replayed |
La fase de sesión de la transacción falló (sin límite cerrado, o reproducción rechazada). Los archivos siguen restaurados; usa el rewind guard: <id> impreso para deshacer. |
rewind: aborted — the pre-rewind guard checkpoint could not be captured |
preRewindCheckpoint: require rechazó la reversión porque falló la captura de la guardia; arregla el almacenamiento (o define warn/off). |
Un checkpoint aparece como (copy) aunque el directorio es un repo |
HEAD no nacido (sin commit inicial): las primitivas de instantánea git requieren HEAD, así que el plugin degrada a copy hasta el primer commit. |
MISSING_CREDENTIAL en ejecuciones headless |
No relacionado con este plugin: no hay DEEPSEEK_API_KEY configurada para el proveedor del modelo. |
| El almacenamiento de instantáneas crece | La poda corre después de cada instantánea y en turn/end (pruneOnTurnEnd); baja maxSnapshots / maxSnapshotBytes, ejecuta /rewind clear, o borra $DSH_HOME/dsh-checkpoint-rewind después de desinstalar. |
Desarrollo
npm install # peer deps: @deepseek-ai/[email protected], schemastery, zod
npm test # node --test test/**/*.test.mjs (incl. suites de proveedores)
npm run test:integration # verificación headless ensamblada (test/integration/)
Sin paso de build: ESM puro — index.mjs/lib/ son los artefactos publicados.
Temas
deepseek-harness, dsh, dsh-plugin, rewind, checkpoint, snapshot, session-replay, session-fork, config-restore, workspace-safety, undo, cordis-plugin
Contribuidores
- @PerryLink — creador y mantenedor: el modelo de checkpoint de tres estados, la costura de proveedores git/copy, la transacción de reversión en tres fases, la línea de tiempo de Ajustes, la documentación, CI/CD y releases.
- @tmpdot (rmUnlucky) — compatibilidad de doble versión para medios v1 (#8), resolución perezosa de
storageDomain(#9), pistas de respuesta en la deduplicación de checkpoints (#10) y el informe del bug del directorio de instantáneas con$DSH_HOMEsin definir (#4). - @shipinliang — informes del contrato wire del panel de checkpoints: el
acceptsUndefinedausente en el parámetrolimit(#5) y el fallo de proxy por el campo privado#deps(#6). - @hwz1456 — informe de captura de checkpoints en el perfil web (#3).
- @Andiii208 — informe de la especificación de publicación de
plugin_check(#2). - @alexchenzl (Ashu) — invitación al listado del DSH Directory (#7).
Instalar desde el mercado de DSH Desktop
Todos los plugins de PerryLink pueden explorarse en el mercado integrado de DSH Desktop: Market → Sources → add source → pegar https://perrylink-dsh-catalog.perrylink.workers.dev/catalog-source.json → seleccionarlo. La instalación sigue pasando por la verificación de identidad npm del mercado y tu confirmación.
Licencia
Apache License 2.0 © 2026 dsh-checkpoint-rewind contributors
Interoperabilidad con otros plugins de DSH
Verificado contra DSH 0.2.0-rc.2 (el runtime para el que se publica este README) y el conjunto de plugins con más estrellas sondeado el 2026-10-05.
Este plugin no interfiere con otros plugins, incluidos los de más estrellas:
- Sin colisión de nombres de herramienta. Todas las herramientas llevan espacio de nombres; ninguna ocupa un nombre desnudo ya perteneciente a una herramienta incluida u otro plugin.
- Sin colisión de clave de servicio. No provee ninguna clave de servicio, así que no puede colisionar en una.
- Sin colisión de slot. No registra ninguna clave de slot de cliente, así que no disputa un asiento
shadows-shipped-ui. - Sin colisión de ruta HTTP. No registra ningún prefijo
webServer. - Sin colisión en la capa de patch. El patch del bundle solo hace
insertde su propia fila; nunca sobrescribe elconfigde una fila incluida. - Sin mutación global. No parchea prototipos, ni reescribe
process.env, ni reemplaza el dispatcher global de fetch.
Los listeners de eventos compartidos no interfieren por construcción. Observa los eventos sensibles al orden fs/edit-intent, fs/write-intent, tools/pre-execute con ctx.on() — el registro de difusión de Cordis, donde cada listener se ejecuta y ninguno puede dejar sin turno a otro. Todos los listeners aquí delegan por next(), así que la cadena nunca se cortocircuita:
tools/pre-execute— also used bycc-safety-net(1576★).
Evidencia estática: dsh-plugin-doctor K10–K13 dan pass en todas las comprobaciones de este repositorio.
PerryLink DSH Plugin Family
Este proyecto forma parte de la familia de plugins de DeepSeek Harness de PerryLink. El registro permanece plegado abajo para que cada README conserve una primera pantalla corta; expándelo para ver cada fila y su estado.