feat: add file checkpointing and rewind_files support

Add support for the file rewind feature from claude-cli-internal PR #11265:

- Add `enable_file_checkpointing` option to ClaudeAgentOptions
- Add `rewind_files(user_message_id)` method to ClaudeSDKClient
- Add `SDKControlRewindFilesRequest` type for the control protocol
- Set `CLAUDE_CODE_ENABLE_SDK_FILE_CHECKPOINTING` env var when enabled

This allows SDK users to enable file checkpointing and rewind tracked
files to their state at any previous user message during a session.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Noah Zweben MacBook 2025-12-08 12:56:28 -08:00
parent db4a6f7c28
commit 0e8753f0db
No known key found for this signature in database
4 changed files with 56 additions and 0 deletions

View file

@ -539,6 +539,21 @@ class Query:
}
)
async def rewind_files(self, user_message_id: str) -> None:
"""Rewind tracked files to their state at a specific user message.
Requires file checkpointing to be enabled via the `enable_file_checkpointing` option.
Args:
user_message_id: UUID of the user message to rewind to
"""
await self._send_control_request(
{
"subtype": "rewind_code",
"user_message_id": user_message_id,
}
)
async def stream_input(self, stream: AsyncIterable[dict[str, Any]]) -> None:
"""Stream input messages to transport.

View file

@ -384,6 +384,10 @@ class SubprocessCLITransport(Transport):
"CLAUDE_AGENT_SDK_VERSION": __version__,
}
# Enable file checkpointing if requested
if self._options.enable_file_checkpointing:
process_env["CLAUDE_CODE_ENABLE_SDK_FILE_CHECKPOINTING"] = "true"
if self._cwd:
process_env["PWD"] = self._cwd

View file

@ -261,6 +261,33 @@ class ClaudeSDKClient:
raise CLIConnectionError("Not connected. Call connect() first.")
await self._query.set_model(model)
async def rewind_files(self, user_message_id: str) -> None:
"""Rewind tracked files to their state at a specific user message.
Requires file checkpointing to be enabled via the `enable_file_checkpointing` option
when creating the ClaudeSDKClient.
Args:
user_message_id: UUID of the user message to rewind to. This should be
the `uuid` field from a `UserMessage` received during the conversation.
Example:
```python
options = ClaudeAgentOptions(enable_file_checkpointing=True)
async with ClaudeSDKClient(options) as client:
await client.query("Make some changes to my files")
async for msg in client.receive_response():
if isinstance(msg, UserMessage):
checkpoint_id = msg.uuid # Save this for later
# Later, rewind to that point
await client.rewind_files(checkpoint_id)
```
"""
if not self._query:
raise CLIConnectionError("Not connected. Call connect() first.")
await self._query.rewind_files(user_message_id)
async def get_server_info(self) -> dict[str, Any] | None:
"""Get server initialization info including available commands and output styles.

View file

@ -673,6 +673,10 @@ class ClaudeAgentOptions:
# Output format for structured outputs (matches Messages API structure)
# Example: {"type": "json_schema", "schema": {"type": "object", "properties": {...}}}
output_format: dict[str, Any] | None = None
# Enable file checkpointing to track file changes during the session.
# When enabled, files can be rewound to their state at any user message
# using `ClaudeSDKClient.rewind_files()`.
enable_file_checkpointing: bool = False
# SDK Control Protocol
@ -713,6 +717,11 @@ class SDKControlMcpMessageRequest(TypedDict):
message: Any
class SDKControlRewindFilesRequest(TypedDict):
subtype: Literal["rewind_code"]
user_message_id: str
class SDKControlRequest(TypedDict):
type: Literal["control_request"]
request_id: str
@ -723,6 +732,7 @@ class SDKControlRequest(TypedDict):
| SDKControlSetPermissionModeRequest
| SDKHookCallbackRequest
| SDKControlMcpMessageRequest
| SDKControlRewindFilesRequest
)