Welcome back! In Chapter 2: Strategy Pattern, we learned how to save code changes using different strategies (like Auto-Commit).
However, saving files is only half the battle. We also need to save Context.
Imagine you are reading a book and you close it. To resume reading later, you need a bookmark. You need to know:
In entireio-cli, the Session State Machine is that bookmark.
Command Line Interfaces (CLIs) have short memories. When you run a command, it starts, does its job, and dies. It forgets everything immediately.
But an AI Agent needs a long memory. It needs to know:
To bridge this gap, entire writes a "Sticky Note" to your hard drive. This is the Session State.
The state is stored as a simple JSON file inside your hidden .git folder:
.git/entire-sessions/<session-id>.json
This ensures that even if you restart your computer, the AI remembers exactly where it left off.
Here is why this is critical.
The Git Hook is a completely different program from the AI Agent. It has no idea an AI is even running.
By reading the Session State file, the Git Hook can say:
"Ah! I see session-123.json exists. I know this file change belongs to that AI session. I will log it correctly."
Without this state file, the Git Hook would treat the AI's changes as anonymous, messy edits.
The structure of this "bookmark" is defined in cmd/entire/cli/session/state.go.
Here is a simplified version of the State struct that acts as our bookmark:
type State struct {
// The unique ID of the conversation
SessionID string `json:"session_id"`
// The "Page Number": The git commit where we started
BaseCommit string `json:"base_commit"`
// The "Line Number": The specific turn/reply we are on
TurnID string `json:"turn_id"`
// Is the session Active, Idle, or Done?
Phase Phase `json:"phase"`
}
Explanation:
To read and write these bookmarks, we use the StateStore. It handles the messy work of finding the .git folder and writing JSON files.
When entireio-cli wakes up, the first thing it does is look for an active bookmark.
// Create the store manager
store, _ := session.NewStateStore()
// Try to load state for a specific session ID
state, err := store.Load(ctx, "session-abc-123")
if state != nil {
fmt.Printf("Resuming session started at: %s", state.StartedAt)
}
Explanation: If state comes back nil, it means no session exists with that ID. It's like looking for a bookmark that isn't there.
Every time the AI does something (like finishing a sentence or writing code), we update the bookmark.
// Update the turn ID to mark progress
state.TurnID = "turn_456"
state.Phase = session.PhaseActive
// Save it back to disk
err := store.Save(ctx, state)
Explanation: This writes the JSON file to .git/entire-sessions/. Now, any other tool (like a Git Hook or a VS Code extension) can read this file and know exactly what is happening.
You might be wondering: "What if the computer crashes while writing the file? Will I get a corrupted half-written JSON file?"
The StateStore uses a technique called Atomic Writing to prevent this.
Here is how state.go implements this safety mechanism.
func (s *StateStore) Save(ctx context.Context, state *State) error {
// 1. Convert struct to JSON text
data, _ := jsonutil.MarshalIndentWithNewline(state, "", " ")
// 2. Define filenames
stateFile := s.stateFilePath(state.SessionID)
tmpFile := stateFile + ".tmp"
// 3. Write to the temporary file first
os.WriteFile(tmpFile, data, 0o600)
// 4. Rename temp file to replace the real file
return os.Rename(tmpFile, stateFile)
}
Explanation: The os.Rename operation is "Atomic" on most operating systems. It happens instantly. This guarantees that session-123.json is either the old version or the new version, but never a corrupted mess.
Let's visualize how the Session State changes over time.
entire "Fix bug".Phase = Active. BaseCommit = HEAD.TurnID changes.Phase = WaitingForUser.Phase = Done (or the file is deleted/cleared).
This lifecycle ensures that if you run entire resume, the system looks at the file, sees Phase = WaitingForUser, and immediately puts you back in the prompt.
In this chapter, you learned:
.git/entire-sessions/.StateStore ensures data safety using Atomic Writes (Write Temp -> Rename).Now we have a way to Store data (Chapter 1), a Strategy to organize it (Chapter 2), and a Memory of what we are doing (Chapter 3).
Next, we need to learn how to trigger these updates automatically when Git events happen. This is done using Lifecycle Hooks.
Generated by Code IQ