מדריך קלוד קוד בעברית

תיעוד 146

החזרת שינויי קבצים לאחור בעזרת נקודות ביקורת (checkpointing)

מעקב אחר שינויים בקבצים במהלך הפעלות סוכן ושחזור קבצים לכל מצב קודם

נקודות ביקורת לקבצים (file checkpointing) עוקבות אחר שינויים בקבצים שבוצעו באמצעות הכלים Write, Edit ו-NotebookEdit במהלך הפעלת סוכן, ומאפשרות לכם להחזיר קבצים לאחור לכל מצב קודם. רוצים לנסות זאת? קפצו אל הדוגמה האינטראקטיבית.

בעזרת נקודות ביקורת, תוכלו:

  • לבטל שינויים לא רצויים על ידי שחזור קבצים למצב תקין וידוע
  • לבחון חלופות על ידי שחזור לנקודת ביקורת וניסיון של גישה אחרת
  • להתאושש משגיאות כאשר הסוכן מבצע שינויים שגויים

[!WARNING] רק שינויים שנעשים דרך הכלים Write, Edit ו-NotebookEdit נמצאים במעקב. שינויים שנעשים דרך פקודות Bash (כמו echo > file.txt או sed -i) אינם נלכדים במערכת נקודות הביקורת, וכך גם עריכות שמחיל סוכן משנה (subagent), למעט מיומנות עם context: fork שרצה בחזית (foreground).

#כיצד פועלות נקודות ביקורת

כאשר מפעילים נקודות ביקורת לקבצים, ה-SDK יוצר גיבויים של קבצים לפני שינוי שלהם דרך הכלים Write, Edit או NotebookEdit. הודעות משתמש בזרם התגובה כוללות מזהה UUID של נקודת ביקורת שבו תוכלו להשתמש כנקודת שחזור.

[!NOTE] החזרת קבצים לאחור משחזרת קבצים בדיסק למצב קודם. היא אינה מחזירה לאחור את השיחה עצמה. היסטוריית השיחה וההקשר נשארים ללא שינוי לאחר קריאה ל-rewindFiles() (ב-TypeScript) או ל-rewind_files() (ב-Python).

כאשר מחזירים לאחור לנקודת ביקורת, Claude Code מוחק את הקבצים שהוא יצר ומשחזר את הקבצים שהוא שינה לתוכנם באותה נקודה. Claude Code מדלג על נתיב במעקב שהוא קישור סימבולי (symlink), קישור קשיח (hard link) או קובץ אחר שאינו קובץ רגיל. הוא גם מדלג על קובץ במעקב שתיקיית האב שלו כבר אינה מפנה למיקום שבו הייתה בזמן נקודת הביקורת, או שאינו יכול לקרוא את הגיבוי שלו בבטחה. המבנה RewindFilesResult סופר כל נתיב שדולג בשדה skippedLinks שלו. דילוג דורש את Claude Code בגרסה v2.1.216 ומעלה. לפני גרסה v2.1.216, פעולת החזרה לאחור כתבה ומחקה דרך קישורים בנתיבים שבמעקב.

#הטמעת נקודות ביקורת

כדי להשתמש בנקודות ביקורת לקבצים, הפעילו אותן באפשרויות שלכם, לכדו מזהי UUID של נקודות ביקורת מזרם התגובה, ולאחר מכן קראו ל-rewindFiles() (ב-TypeScript) או ל-rewind_files() (ב-Python) כאשר תצטרכו לשחזר.

הדוגמה הבאה מציגה את התהליך המלא: הפעלת נקודות ביקורת, לכידת ה-UUID של נקודת הביקורת ומזהה ההפעלה (session ID) מזרם התגובה, ולאחר מכן חידוש ההפעלה מאוחר יותר כדי להחזיר קבצים לאחור. כל שלב מוסבר בפירוט בהמשך. הדוגמאות בחלק זה משתמשות בהנחיה "Refactor the authentication module". הריצו אותן בפרויקט שמכיל מודול אימות, או שנו את ההנחיה כך שתציין קבצים שקיימים בפרויקט שלכם, כדי שתוכלו לראות את השינויים בקבצים ולראות כיצד ההחזרה לאחור משחזרת אותם.

#Python

import asyncio
from claude_agent_sdk import (
    ClaudeSDKClient,
    ClaudeAgentOptions,
    UserMessage,
    ResultMessage,
)


async def main():
    
# Step 1: Enable checkpointing
    options = ClaudeAgentOptions(
        enable_file_checkpointing=True,
        permission_mode="acceptEdits",  
# Auto-accept file edits without prompting
        extra_args={
            "replay-user-messages": None
        },  
# Required to receive checkpoint UUIDs in the response stream
    )

    checkpoint_id = None
    session_id = None

    
# Run the query and capture checkpoint UUID and session ID
    async with ClaudeSDKClient(options) as client:
        await client.query("Refactor the authentication module")

        
# Step 2: Capture checkpoint UUID from the first user message
        async for message in client.receive_response():
            if isinstance(message, UserMessage) and message.uuid and not checkpoint_id:
                checkpoint_id = message.uuid
            if isinstance(message, ResultMessage) and not session_id:
                session_id = message.session_id

    
# Step 3: Later, rewind by resuming the session with an empty prompt
    if checkpoint_id and session_id:
        async with ClaudeSDKClient(
            ClaudeAgentOptions(enable_file_checkpointing=True, resume=session_id)
        ) as client:
            await client.query("")  
# Empty prompt to open the connection
            async for message in client.receive_response():
                await client.rewind_files(checkpoint_id)
                break
        print(f"Rewound to checkpoint: {checkpoint_id}")


asyncio.run(main())

#TypeScript

import { query } from "@anthropic-ai/claude-agent-sdk";

async function main() {
  // Step 1: Enable checkpointing
  const opts = {
    enableFileCheckpointing: true,
    permissionMode: "acceptEdits" as const, // Auto-accept file edits without prompting
    extraArgs: { "replay-user-messages": null } // Required to receive checkpoint UUIDs in the response stream
  };

  const response = query({
    prompt: "Refactor the authentication module",
    options: opts
  });

  let checkpointId: string | undefined;
  let sessionId: string | undefined;

  // Step 2: Capture checkpoint UUID from the first user message
  try {
    for await (const message of response) {
      if (message.type === "user" && message.uuid && !checkpointId) {
        checkpointId = message.uuid;
      }
      if ("session_id" in message && !sessionId) {
        sessionId = message.session_id;
      }
    }
  } catch (error) {
    // A single-shot query() throws after yielding an error result. If the
    // failure was an error result, sessionId and checkpointId were already
    // captured by the loop above; connection or process failures yield no
    // result message.
    console.error(`Session ended with an error: ${error}`);
  }

  // Step 3: Later, rewind by resuming the session with an empty prompt
  if (checkpointId && sessionId) {
    const rewindQuery = query({
      prompt: "", // Empty prompt to open the connection
      options: { ...opts, resume: sessionId }
    });

    for await (const msg of rewindQuery) {
      await rewindQuery.rewindFiles(checkpointId);
      break;
    }
    console.log(`Rewound to checkpoint: ${checkpointId}`);
  }
}

main();
  1. הפעלת נקודות ביקורת

    הגדירו את אפשרויות ה-SDK שלכם כדי להפעיל נקודות ביקורת ולקבל מזהי UUID של נקודות ביקורת:

    אפשרותPythonTypeScriptתיאור
    הפעלת נקודות ביקורתenable_file_checkpointing=TrueenableFileCheckpointing: trueמעקב אחר שינויים בקבצים לצורך החזרה לאחור
    קבלת מזהי UUID של נקודות ביקורתextra_args={"replay-user-messages": None}extraArgs: { 'replay-user-messages': null }נדרש כדי לקבל מזהי UUID של הודעות משתמש בזרם

    Python:

    options = ClaudeAgentOptions(
        enable_file_checkpointing=True,
        permission_mode="acceptEdits",
        extra_args={"replay-user-messages": None},
    )
    
    async with ClaudeSDKClient(options) as client:
        await client.query("Refactor the authentication module")

    TypeScript:

    const response = query({
      prompt: "Refactor the authentication module",
      options: {
        enableFileCheckpointing: true,
        permissionMode: "acceptEdits" as const,
        extraArgs: { "replay-user-messages": null }
      }
    });
  2. לכידת מזהה UUID של נקודת ביקורת ומזהה הפעלה

    כאשר האפשרות replay-user-messages מוגדרת (כפי שמוצג למעלה), לכל הודעת משתמש בזרם התגובה יש UUID המשמש כנקודת ביקורת.

    עבור רוב מקרי השימוש, לכדו את ה-UUID של הודעת המשתמש הראשונה (message.uuid). החזרה לאחור אליו משחזרת את הקבצים שבמעקב למצבם המקורי. כדי לשמור מספר נקודות ביקורת ולהחזיר לאחור למצבי ביניים, ראו מספר נקודות שחזור.

    לכידת מזהה ההפעלה (message.session_id) היא אופציונלית. אתם זקוקים לה רק אם ברצונכם להחזיר לאחור מאוחר יותר, לאחר שהזרם מסתיים. אם אתם קוראים ל-rewindFiles() באופן מיידי תוך כדי עיבוד הודעות (כפי שעושה הדוגמה בסעיף נקודת ביקורת לפני פעולות מסוכנות), תוכלו לדלג על לכידת מזהה ההפעלה.

    Python:

    checkpoint_id = None
    session_id = None
    
    async for message in client.receive_response():

#Capture the first user message UUID as the checkpoint

   if isinstance(message, UserMessage) and message.uuid and checkpoint_id is None:
       checkpoint_id = message.uuid

#Capture session ID from the result message

   if isinstance(message, ResultMessage):
       session_id = message.session_id

**TypeScript**:
```typescript
let checkpointId: string | undefined;
let sessionId: string | undefined;

for await (const message of response) {
  // Capture the first user message UUID as the checkpoint
  if (message.type === "user" && message.uuid && !checkpointId) {
    checkpointId = message.uuid;
  }
  // Capture session ID from any message that has it
  if ("session_id" in message) {
    sessionId = message.session_id;
  }
}
  1. החזרת קבצים לאחור

    כדי להחזיר לאחור לאחר שהזרם מסתיים, חדשו את ההפעלה עם הנחיה ריקה וקראו ל-rewind_files() (ב-Python) או ל-rewindFiles() (ב-TypeScript) עם ה-UUID של נקודת הביקורת שלכם. תוכלו גם להחזיר לאחור במהלך הזרם. ראו את נקודת ביקורת לפני פעולות מסוכנות עבור תבנית זו.

    Python:

    async with ClaudeSDKClient(
        ClaudeAgentOptions(enable_file_checkpointing=True, resume=session_id)
    ) as client:
        await client.query("")

#Empty prompt to open the connection

   async for message in client.receive_response():
       if checkpoint_id:
           await client.rewind_files(checkpoint_id)
       break

**TypeScript**:
```typescript
const rewindQuery = query({
  prompt: "", // Empty prompt to open the connection
  options: { ...opts, resume: sessionId }
});

for await (const msg of rewindQuery) {
  if (checkpointId) {
    await rewindQuery.rewindFiles(checkpointId);
  }
  break;
}

אם תלכדו את מזהה ההפעלה ואת מזהה נקודת הביקורת, תוכלו להחזיר לאחור גם מתוך ה-CLI. פקודה זו דורשת את קובץ ההפעלה claude, שמגיע מתוך התקנת Claude Code ואינו מותקן על ידי חבילת ה-SDK. ה-SDK מפעיל נקודות ביקורת עבורכם, אך כאשר אתם מריצים את claude -p ישירות, עליכם להגדיר את משתנה הסביבה CLAUDE_CODE_ENABLE_SDK_FILE_CHECKPOINTING:

CLAUDE_CODE_ENABLE_SDK_FILE_CHECKPOINTING=true claude -p --resume <session-id> --rewind-files <checkpoint-uuid>

הדגל --rewind-files אינו מופיע בפלט של claude --help, אך ה-CLI מקבל אותו כפי שמוצג. כאשר ההחזרה לאחור מצליחה, הפקודה מדפיסה Files rewound to state at message <checkpoint-uuid> ויוצאת מבלי לשלוח הנחיה.

#תבניות נפוצות

תבניות אלה מציגות דרכים שונות ללכידה ולשימוש במזהי UUID של נקודות ביקורת בהתאם למקרה השימוש שלכם.

#נקודת ביקורת לפני פעולות מסוכנות

תבנית זו שומרת רק את ה-UUID העדכני ביותר של נקודת הביקורת, ומעדכנת אותו לפני כל תור של הסוכן. אם משהו משתבש במהלך העיבוד, תוכלו להחזיר לאחור מיד למצב הבטוח האחרון ולצאת מהלולאה.

לפני הרצת דוגמה זו, החליפו את your_revert_condition (ב-Python) או את yourRevertCondition (ב-TypeScript) בבדיקה משלכם, כגון זיהוי שגיאה או כשל באימות. שומר המקום אינו מוגדר בדוגמה.

#Python

import asyncio
from claude_agent_sdk import ClaudeSDKClient, ClaudeAgentOptions, UserMessage


async def main():
    options = ClaudeAgentOptions(
        enable_file_checkpointing=True,
        permission_mode="acceptEdits",
        extra_args={"replay-user-messages": None},
    )

    safe_checkpoint = None

    async with ClaudeSDKClient(options) as client:
        await client.query("Refactor the authentication module")

        async for message in client.receive_response():
            
# Update checkpoint before each agent turn starts
            
# This overwrites the previous checkpoint. Only keep the latest
            if isinstance(message, UserMessage) and message.uuid:
                safe_checkpoint = message.uuid

            
# Decide when to revert based on your own logic
            
# For example: error detection, validation failure, or user input
            if your_revert_condition and safe_checkpoint:
                await client.rewind_files(safe_checkpoint)
                
# Exit the loop after rewinding, files are restored
                break


asyncio.run(main())

#TypeScript

import { query } from "@anthropic-ai/claude-agent-sdk";

async function main() {
  const response = query({
    prompt: "Refactor the authentication module",
    options: {
      enableFileCheckpointing: true,
      permissionMode: "acceptEdits" as const,
      extraArgs: { "replay-user-messages": null }
    }
  });

  let safeCheckpoint: string | undefined;

  for await (const message of response) {
    // Update checkpoint before each agent turn starts
    // This overwrites the previous checkpoint. Only keep the latest
    if (message.type === "user" && message.uuid) {
      safeCheckpoint = message.uuid;
    }

    // Decide when to revert based on your own logic
    // For example: error detection, validation failure, or user input
    if (yourRevertCondition && safeCheckpoint) {
      await response.rewindFiles(safeCheckpoint);
      // Exit the loop after rewinding, files are restored
      break;
    }
  }
}

main();

#מספר נקודות שחזור

אם Claude מבצע שינויים לאורך מספר תורות, ייתכן שתרצו להחזיר לאחור לנקודה מסוימת ולא עד ההתחלה. לדוגמה, אם Claude משכתב קובץ בתור הראשון ומוסיף בדיקות בתור השני, ייתכן שתרצו לשמור את השכתוב אך לבטל את הבדיקות.

תבנית זו שומרת את כל מזהי ה-UUID של נקודות הביקורת במערך יחד עם מטא-נתונים. לאחר שההפעלה מסתיימת, תוכלו להחזיר לאחור לכל נקודת ביקורת קודמת:

#Python

import asyncio
from dataclasses import dataclass
from datetime import datetime
from claude_agent_sdk import (
    ClaudeSDKClient,
    ClaudeAgentOptions,
    UserMessage,
    ResultMessage,
)


# Store checkpoint metadata for better tracking
@dataclass
class Checkpoint:
    id: str
    description: str
    timestamp: datetime


async def main():
    options = ClaudeAgentOptions(
        enable_file_checkpointing=True,
        permission_mode="acceptEdits",
        extra_args={"replay-user-messages": None},
    )

    checkpoints = []
    session_id = None

    async with ClaudeSDKClient(options) as client:
        await client.query("Refactor the authentication module")

        async for message in client.receive_response():
            if isinstance(message, UserMessage) and message.uuid:
                checkpoints.append(
                    Checkpoint(
                        id=message.uuid,
                        description=f"After turn {len(checkpoints) + 1}",
                        timestamp=datetime.now(),
                    )
                )
            if isinstance(message, ResultMessage) and not session_id:
                session_id = message.session_id

    
# Later: rewind to any checkpoint by resuming the session
    if checkpoints and session_id:
        target = checkpoints[0]  
# Pick any checkpoint
        async with ClaudeSDKClient(
            ClaudeAgentOptions(enable_file_checkpointing=True, resume=session_id)
        ) as client:
            await client.query("")  
# Empty prompt to open the connection
            async for message in client.receive_response():
                await client.rewind_files(target.id)
                break
        print(f"Rewound to: {target.description}")


asyncio.run(main())

#TypeScript

import { query } from "@anthropic-ai/claude-agent-sdk";

// Store checkpoint metadata for better tracking
interface Checkpoint {
  id: string;
  description: string;
  timestamp: Date;
}

async function main() {
  const opts = {
    enableFileCheckpointing: true,
    permissionMode: "acceptEdits" as const,
    extraArgs: { "replay-user-messages": null }
  };

  const response = query({
    prompt: "Refactor the authentication module",
    options: opts
  });

  const checkpoints: Checkpoint[] = [];
  let sessionId: string | undefined;

  try {
    for await (const message of response) {
      if (message.type === "user" && message.uuid) {
        checkpoints.push({
          id: message.uuid,
          description: `After turn ${checkpoints.length + 1}`,
          timestamp: new Date()
        });
      }
      if ("session_id" in message && !sessionId) {
        sessionId = message.session_id;
      }
    }
  } catch (error) {
    // A single-shot query() throws after yielding an error result. If the
    // failure was an error result, sessionId and the checkpoints array were
    // already populated by the loop above; connection or process failures
    // yield no result message.
    console.error(`Session ended with an error: ${error}`);
  }

  // Later: rewind to any checkpoint by resuming the session
  if (checkpoints.length > 0 && sessionId) {
    const target = checkpoints[0]; // Pick any checkpoint
    const rewindQuery = query({
      prompt: "", // Empty prompt to open the connection
      options: { ...opts, resume: sessionId }
    });

    for await (const msg of rewindQuery) {
      await rewindQuery.rewindFiles(target.id);
      break;
    }
    console.log(`Rewound to: ${target.description}`);
  }
}

main();

#התנסו בעצמכם

דוגמה מלאה זו יוצרת קובץ עזר קטן, גורמת לסוכן להוסיף הערות תיעוד, מציגה לכם את השינויים, ולאחר מכן שואלת אם ברצונכם להחזיר לאחור.

לפני שתתחילו, ודאו שמותקן אצלכם Claude Agent SDK.

  1. יצירת קובץ בדיקה

    צרו קובץ חדש בשם utils.py (ב-Python) או utils.ts (ב-TypeScript) והדביקו את הקוד הבא:

    Python (utils.py):

    def add(a, b):
        return a + b
    
    
    def subtract(a, b):
        return a - b
    
    
    def multiply(a, b):
        return a * b
    
    
    def divide(a, b):
        if b == 0:
            raise ValueError("Cannot divide by zero")
        return a / b

    TypeScript (utils.ts):

    export function add(a: number, b: number): number {
      return a + b;
    }
    
    export function subtract(a: number, b: number): number {
      return a - b;
    }
    
    export function multiply(a: number, b: number): number {
      return a * b;
    }
    
    export function divide(a: number, b: number): number {
      if (b === 0) {
        throw new Error("Cannot divide by zero");
      }
      return a / b;
    }
  2. הרצת הדוגמה האינטראקטיבית

    צרו קובץ חדש בשם try_checkpointing.py (ב-Python) או try_checkpointing.ts (ב-TypeScript) באותה תיקייה שבה נמצא קובץ העזר שלכם, והדביקו את הקוד הבא.

    סקריפט זה מבקש מ-Claude להוסיף הערות תיעוד לקובץ העזר שלכם, ולאחר מכן מאפשר לכם להחזיר לאחור ולשחזר את הקובץ המקורי.

    Python (try_checkpointing.py):

    import asyncio
    from claude_agent_sdk import (
        ClaudeSDKClient,
        ClaudeAgentOptions,
        UserMessage,
        ResultMessage,
    )
    
    
    async def main():

#Configure the SDK with checkpointing enabled

#- enable_file_checkpointing: Track file changes for rewinding

#- permission_mode: Auto-accept file edits without prompting

#- extra_args: Required to receive user message UUIDs in the stream

   options = ClaudeAgentOptions(
       enable_file_checkpointing=True,
       permission_mode="acceptEdits",
       extra_args={"replay-user-messages": None},
   )

   checkpoint_id = None  

#Store the user message UUID for rewinding

   session_id = None  

#Store the session ID for resuming

   print("Running agent to add doc comments to utils.py...\n")

#Run the agent and capture checkpoint data from the response stream

   async with ClaudeSDKClient(options) as client:
       await client.query("Add doc comments to utils.py")

       async for message in client.receive_response():

#Capture the first user message UUID - this is our restore point

           if isinstance(message, UserMessage) and message.uuid and not checkpoint_id:
               checkpoint_id = message.uuid

#Capture the session ID so we can resume later

           if isinstance(message, ResultMessage):
               session_id = message.session_id

   print("Done! Open utils.py to see the added doc comments.\n")

#Ask the user if they want to rewind the changes

   if checkpoint_id and session_id:
       response = input("Rewind to remove the doc comments? (y/n): ")

       if response.lower() == "y":

#Resume the session with an empty prompt, then rewind

           async with ClaudeSDKClient(
               ClaudeAgentOptions(enable_file_checkpointing=True, resume=session_id)
           ) as client:
               await client.query("")  

#Empty prompt opens the connection

               async for message in client.receive_response():
                   await client.rewind_files(checkpoint_id)  

#Restore files

                   break

           print(
               "\n✓ File restored! Open utils.py to verify the doc comments are gone."
           )
       else:
           print("\nKept the modified file.")

asyncio.run(main())


**TypeScript (`try_checkpointing.ts`)**:
```typescript
import { query } from "@anthropic-ai/claude-agent-sdk";
import * as readline from "readline";

async function main() {
  // Configure the SDK with checkpointing enabled
  // - enableFileCheckpointing: Track file changes for rewinding
  // - permissionMode: Auto-accept file edits without prompting
  // - extraArgs: Required to receive user message UUIDs in the stream
  const opts = {
    enableFileCheckpointing: true,
    permissionMode: "acceptEdits" as const,
    extraArgs: { "replay-user-messages": null }
  };

  let sessionId: string | undefined; // Store the session ID for resuming
  let checkpointId: string | undefined; // Store the user message UUID for rewinding

  console.log("Running agent to add doc comments to utils.ts...\n");

  // Run the agent and capture checkpoint data from the response stream
  const response = query({
    prompt: "Add doc comments to utils.ts",
    options: opts
  });

  try {
    for await (const message of response) {
      // Capture the first user message UUID - this is our restore point
      if (message.type === "user" && message.uuid && !checkpointId) {
        checkpointId = message.uuid;
      }
      // Capture the session ID so we can resume later
      if ("session_id" in message) {
        sessionId = message.session_id;
      }
    }
  } catch (error) {
   // A single-shot query() throws after yielding an error result. If the
   // failure was an error result, checkpointId and sessionId were already
   // captured by the loop above; connection or process failures yield no
   // result message.
   console.error(`Session ended with an error: ${error}`);
  }

  console.log("Done! Open utils.ts to see the added doc comments.\n");

  // Ask the user if they want to rewind the changes
  if (checkpointId && sessionId) {
    const rl = readline.createInterface({
      input: process.stdin,
      output: process.stdout
    });

    const answer = await new Promise<string>((resolve) => {
      rl.question("Rewind to remove the doc comments? (y/n): ", resolve);
    });
    rl.close();

    if (answer.toLowerCase() === "y") {
      // Resume the session with an empty prompt, then rewind
      const rewindQuery = query({
        prompt: "", // Empty prompt opens the connection
        options: { ...opts, resume: sessionId }
      });

      for await (const msg of rewindQuery) {
        await rewindQuery.rewindFiles(checkpointId); // Restore files
        break;
      }

      console.log("\n✓ File restored! Open utils.ts to verify the doc comments are gone.");
    } else {
      console.log("\nKept the modified file.");
    }
  }
}

main();
  1. הרצת הדוגמה

    הריצו את הסקריפט מתוך אותה תיקייה שבה נמצא קובץ העזר שלכם.

    [!TIP] פתחו את קובץ העזר שלכם (utils.py או utils.ts) בסביבת הפיתוח או בעורך שלכם לפני הרצת הסקריפט. תראו את הקובץ מתעדכן בזמן אמת כשהסוכן מוסיף הערות תיעוד, ולאחר מכן חוזר למצבו המקורי כאשר תבחרו להחזיר לאחור.

    Python:

    python try_checkpointing.py

    TypeScript:

    npx tsx try_checkpointing.ts

    תראו את הסוכן מוסיף הערות תיעוד, ולאחר מכן תוצג שאלה האם ברצונכם להחזיר לאחור. אם תבחרו כן, הקובץ ישוחזר למצבו המקורי.

#מגבלות

לנקודות ביקורת לקבצים יש את המגבלות הבאות:

מגבלהתיאור
כלי Write/Edit/NotebookEdit בלבדשינויים שנעשו באמצעות פקודות Bash אינם נמצאים במעקב
עריכות של סוכן משנהעריכות שמחיל סוכן משנה אינן נמצאות במעקב ואינן משוחזרות, למעט מיומנות עם context: fork שרצה בחזית. השתמשו ב-git כדי לבטל עריכות שאינן במעקב
אותה הפעלהנקודות ביקורת מקושרות להפעלה שיצרה אותן
תוכן קבצים בלבדיצירה, העברה או מחיקה של תיקיות אינן מתבטלות בעת החזרה לאחור
קבצים מקומייםקבצים מרוחקים או קבצי רשת אינם נמצאים במעקב

#פתרון בעיות

#אפשרויות נקודות ביקורת אינן מזוהות

אם enableFileCheckpointing או rewindFiles() אינם זמינים, ייתכן שאתם משתמשים בגרסת SDK ישנה יותר.

פתרון: עדכנו לגרסת ה-SDK העדכנית ביותר:

  • Python: pip install --upgrade claude-agent-sdk
  • TypeScript: npm install @anthropic-ai/claude-agent-sdk@latest

#להודעות משתמש אין מזהי UUID

אם message.uuid הוא undefined או חסר, אינכם מקבלים מזהי UUID של נקודות ביקורת.

סיבה: האפשרות replay-user-messages אינה מוגדרת.

פתרון: הוסיפו extra_args={"replay-user-messages": None} (ב-Python) או extraArgs: { 'replay-user-messages': null } (ב-TypeScript) לאפשרויות שלכם.

#שגיאת "No file checkpoint found for this message"

שגיאה זו מתרחשת כאשר נתוני נקודת הביקורת אינם קיימים עבור ה-UUID של הודעת המשתמש שצוין.

סיבות נפוצות:

  • נקודות ביקורת לקבצים לא הופעלו בהפעלה המקורית (enable_file_checkpointing או enableFileCheckpointing לא הוגדר כ-true)
  • ההפעלה לא הושלמה כראוי לפני הניסיון לחדש ולהחזיר לאחור

פתרון: ודאו שהוגדר enable_file_checkpointing=True (ב-Python) או enableFileCheckpointing: true (ב-TypeScript) בהפעלה המקורית, ולאחר מכן השתמשו בתבנית המוצגת בדוגמאות: לכדו את ה-UUID של הודעת המשתמש הראשונה, השלימו את ההפעלה במלואה, ואז חדשו עם הנחיה ריקה וקראו ל-rewindFiles() פעם אחת.

#שגיאת "File rewinding is not enabled"

שגיאה זו מתרחשת כאשר מנסים לבצע החזרה לאחור לא אינטראקטיבית מבלי שנקודות ביקורת הופעלו: הרצת claude -p בלבד עם --rewind-files, או הרצת הפעלת SDK, כולל הפעלה שחודשה, שהאפשרויות שלה אינן מפעילות נקודות ביקורת. ה-SDK מגדיר את משתנה הסביבה CLAUDE_CODE_ENABLE_SDK_FILE_CHECKPOINTING באופן פנימי רק כאשר enable_file_checkpointing (ב-Python) או enableFileCheckpointing (ב-TypeScript) מופעל בהפעלה שמבצעת את ההחזרה לאחור. ה-CLI הישיר לעולם אינו מגדיר אותו.

פתרון: עבור CLI ישיר, הגדירו את משתנה הסביבה בעת הרצת הפקודה:

CLAUDE_CODE_ENABLE_SDK_FILE_CHECKPOINTING=true claude -p --resume <session-id> --rewind-files <checkpoint-uuid>

עבור ה-SDK, הגדירו enable_file_checkpointing=True (ב-Python) או enableFileCheckpointing: true (ב-TypeScript) בהפעלה שחודשה, כפי שעושות הדוגמאות בדף זה.

#שגיאת "ProcessTransport is not ready for writing"

שגיאה זו מתרחשת כאשר קוראים ל-rewindFiles() או ל-rewind_files() לאחר שסיימתם לעבור בלולאה על התגובה. החיבור לתהליך ה-CLI נסגר כאשר הלולאה מסתיימת.

פתרון: חדשו את ההפעלה עם הנחיה ריקה, ולאחר מכן קראו להחזרה לאחור בשאילתה החדשה:

#Python

# Resume session with empty prompt, then rewind
async with ClaudeSDKClient(
    ClaudeAgentOptions(enable_file_checkpointing=True, resume=session_id)
) as client:
    await client.query("")
    async for message in client.receive_response():
        if checkpoint_id:
            await client.rewind_files(checkpoint_id)
        break

#TypeScript

// Resume session with empty prompt, then rewind
const rewindQuery = query({
  prompt: "",
  options: { ...opts, resume: sessionId }
});

try {
  for await (const msg of rewindQuery) {
    if (checkpointId) {
      await rewindQuery.rewindFiles(checkpointId);
    }
    break;
  }
} catch (error) {
  // An error here means the rewind didn't complete, for example the checkpoint
  // wasn't found or the session couldn't be resumed.
  console.error(`Rewind session ended with an error: ${error}`);
}

#השלבים הבאים

  • הפעלות (Sessions): למדו כיצד לחדש הפעלות, פעולה הנדרשת לצורך החזרה לאחור לאחר שהזרם מסתיים. מכסה מזהי הפעלה, חידוש שיחות ופיצול הפעלות (session forking).
  • הרשאות (Permissions): הגדירו באילו כלים Claude יכול להשתמש וכיצד מאושרים שינויים בקבצים. שימושי אם ברצונכם בשליטה רבה יותר על מועד ביצוע העריכות.
  • מדריך ה-SDK ל-TypeScript (TypeScript SDK reference): תיעוד API מלא הכולל את כל האפשרויות עבור query() והמתודה rewindFiles().
  • מדריך ה-SDK ל-Python (Python SDK reference): תיעוד API מלא הכולל את כל האפשרויות עבור ClaudeAgentOptions והמתודה rewind_files().