Repo-local checkpointing and recovery for Claude Code runs.
daedalus wraps Claude Code, creates checkpoints before configured mutation tools, and gives you two recovery paths:
ddl restorerestores the workspace to a checkpointddl rewindrestores the workspace and resumes the Claude-backed run when rewind data was captured
Git still owns commit history. daedalus handles the failure mode where an agent run was going fine until one edit or shell command damaged the working state.
Status: early and intentionally narrow.
daedalusis currently Claude-first and only supports Claude Code forddl run.
Run Claude under daedalus:
ddl run -- claudeIf a protected action goes wrong:
ddl log
ddl restore <checkpoint_id>If the checkpoint came from a Claude-backed run and rewind state was captured:
ddl rewind <checkpoint_id>That is the whole model:
- checkpoint before risky action
- inspect recent checkpoints
- restore files, or restore files and resume the run
AI coding workflows have a specific failure mode:
- the agent has already made useful progress
- a later edit or shell command damages the workspace
- a normal Git revert is too coarse or too late
- starting a fresh agent session throws away useful context
daedalus is built for that case. It does not replace Git. It adds short-range recovery around live agent actions.
Install from crates.io after the first publish:
cargo install daedalus-cliThe published package is daedalus-cli. The installed command remains ddl.
Install from a local checkout:
cargo install --path crates/ddlInitialize per-repo Daedalus state:
ddl initInspect or edit checkpoint rules for the current checkout:
ddl config
ddl config editRun Claude under protection:
ddl run -- claudeInspect recent checkpoints and recover when needed:
ddl log
ddl restore <checkpoint_id>
ddl rewind <checkpoint_id>ddl log opens an interactive recovery console in a TTY and prints plain text in non-interactive contexts.
daedalus owns the Claude run and checkpoints before configured mutation boundaries.
Today that means:
Edit(*)MultiEdit(*)Write(*)- configured
Bash(...)rules
ddl init writes per-repo config under ~/.daedalus/repos/<repo-id>/config.json by default
or $DAEDALUS_HOME/repos/<repo-id>/config.json when overridden:
{
"checkpointing": {
"before": [
"Edit(*)",
"MultiEdit(*)",
"Write(*)",
"Bash(rm:*)",
"Bash(mv:*)"
]
}
}Recovery flow:
Claude run
|
v
checkpoint before protected action
|
v
bad action lands
|
+-+-------------------+
| |
v v
restore rewind
files only files + Claude session resume
Use ddl restore when you want the workspace back at a checkpoint.
Use ddl rewind when all of the following are true:
- the checkpoint came from a Claude-backed run owned by
daedalus - workspace snapshot data still exists
- Claude rewind state was captured for that checkpoint
ddl rewind first restores the checkpoint, then attempts to resume the same Claude session. If Claude context is unavailable, or the checkpoint is not rewindable, ddl rewind fails clearly and ddl restore remains available.
Protected today:
- workspace files
- per-repo checkpoint metadata under
~/.daedalus/repos/<repo-id>/ - Claude-backed local rewind snapshot data when captured
Checkpoint coverage today:
Edit(*)MultiEdit(*)Write(*)- configured
Bash(...)
For Claude-backed runs owned by daedalus, checkpoints also record:
- the Claude session id
- a best-effort local Claude rewind snapshot under
~/.daedalus/repos/<repo-id>/runtime/<run_id>/claude-checkpoints/<checkpoint_id>/
That snapshot currently covers:
~/.claude/projects/<escaped-cwd>/<session_id>.jsonl~/.claude/file-history/<session_id>/
The v1 scope is intentionally narrow:
- Claude Code only. Other runtimes are unsupported for
ddl run. ddl rewindonly works for Claude-backed checkpoints with captured rewind state..gitis out of scope.daedalusdoes not snapshot, restore, or protect repo metadata.- External side effects outside the workspace are not rewound.
- The current Claude snapshot is best-effort and does not cover all of
~/.claude, subagent state, task state, telemetry, or vendor UI state. - Symlink snapshots are rejected.
ddl restorereplaces the current workspace snapshot and removes files created after the checkpoint while leaving.gitandtargetuntouched.
ddl init
ddl config [path|edit]
ddl where
ddl run -- claude <args...>
ddl shell -- <command>
ddl log
ddl diff [checkpoint_a] [checkpoint_b]
ddl restore <checkpoint_id>
ddl rewind <checkpoint_id>ddl initcreates per-repo state under~/.daedalusby default, initializes the shadow git repository, and writes the default checkpointing config there on first init- re-running
ddl initpreserves an existingconfig.jsonand reports that the repo is already initialized ddl configshows the current repo config andddl config editopens it in$EDITORddl whereprints the current checkout's repo root, state id, state directory, and key metadata paths so users can inspect or remove stored state directlyddl runlaunches Claude from the repo root with checkpoint protection enabledddl shellruns a shell command through the same checkpoint matcherddl logshows recent checkpoints and available recovery actionsddl diffcompares checkpoint snapshotsddl restoreis destructive workspace recovery onlyddl rewindis workspace recovery plus Claude resume when the checkpoint is rewindable
The current shell-first base includes:
- per-repo state under
~/.daedalus/ - a shadow git-backed snapshot store
- automatic checkpointing before configured Bash rules
- Claude
PreToolUsehook checkpointing forEdit,MultiEdit,Write, andBash - interactive
ddl logrecovery
The main question for the project is still practical: does restore plus rewind materially improve real AI-assisted development workflows.