|
| 1 | +# Session Persistence |
| 2 | + |
| 3 | +Deep Code stores per-project session history in the local user directory. This history powers `/resume`, `/continue`, and `/undo`, and it remains available after the current terminal process exits. |
| 4 | + |
| 5 | +## Storage Location |
| 6 | + |
| 7 | +Each project has its own storage directory: |
| 8 | + |
| 9 | +```text |
| 10 | +~/.deepcode/projects/<project-code>/ |
| 11 | +``` |
| 12 | + |
| 13 | +`<project-code>` is generated from the project root path. Normal paths are converted into safe directory names. When the path would be too long, Deep Code keeps part of the project name and appends a stable hash so the storage path stays safe. |
| 14 | + |
| 15 | +The project storage directory contains these main files and directories: |
| 16 | + |
| 17 | +| Path | Description | |
| 18 | +| ---- | ----------- | |
| 19 | +| `sessions-index.json` | Session index for the current project, including the session list and summary metadata. | |
| 20 | +| `<session-id>.jsonl` | Message log for one session. Each line is one JSON message. | |
| 21 | +| `file-history/.git` | Internal Git repository used for code checkpoints restored by `/undo`. | |
| 22 | + |
| 23 | +## Persisted Data |
| 24 | + |
| 25 | +### Session Index |
| 26 | + |
| 27 | +`sessions-index.json` stores recent session entries. Each entry includes: |
| 28 | + |
| 29 | +- Session ID, title, creation time, and update time. |
| 30 | +- Session status, such as `pending`, `processing`, `completed`, `failed`, `interrupted`, `ask_permission`, or `waiting_for_user`. |
| 31 | +- Latest assistant reply, thinking content, refusal reason, and failure reason. |
| 32 | +- Latest tool-call data, token usage, and active token count. |
| 33 | +- Metadata for subprocesses still tracked by the session. |
| 34 | + |
| 35 | +The default session title comes from the first 100 characters of the first user prompt. Renaming a session from the session list updates the title in the index. |
| 36 | + |
| 37 | +### Message Files |
| 38 | + |
| 39 | +Each session has a separate JSONL message file named `<session-id>.jsonl`. Messages are appended in order. Common fields include: |
| 40 | + |
| 41 | +| Field | Description | |
| 42 | +| ----- | ----------- | |
| 43 | +| `id` | Message ID. | |
| 44 | +| `sessionId` | Owning session ID. | |
| 45 | +| `role` | Message role: `system`, `user`, `assistant`, or `tool`. | |
| 46 | +| `content` | Text content. | |
| 47 | +| `contentParams` | Structured content, such as image input. | |
| 48 | +| `messageParams` | Model message parameters, such as tool call IDs, tool calls, and reasoning content. | |
| 49 | +| `visible` | Whether the message is shown in the UI. | |
| 50 | +| `compacted` | Whether the message has been replaced by long-session compaction. | |
| 51 | +| `checkpointHash` | Code checkpoint hash associated with `/undo`. | |
| 52 | +| `meta` | Extra metadata for tool display, skills, permissions, summaries, and related features. | |
| 53 | + |
| 54 | +When loading a message file, Deep Code parses JSON one line at a time. Malformed lines are ignored so the remaining usable history can still be loaded. |
| 55 | + |
| 56 | +### Code Checkpoints |
| 57 | + |
| 58 | +Deep Code stores code checkpoints in `file-history/.git`. This repository is only internal file history; it is not the project Git repository. |
| 59 | + |
| 60 | +- A new session initializes an internal branch named after the session ID. |
| 61 | +- Before each user prompt, Deep Code records the state of files it already tracks. |
| 62 | +- Before and after tool-based file mutations, Deep Code records the relevant file state as needed. |
| 63 | +- `checkpointHash` on user messages links a conversation position to a code state. |
| 64 | + |
| 65 | +Checkpoints only cover files Deep Code has tracked. Unrelated files are not arbitrarily rewritten by `/undo`. |
| 66 | + |
| 67 | +## Session Lifecycle |
| 68 | + |
| 69 | +### Creating A Session |
| 70 | + |
| 71 | +When creating a new session, Deep Code: |
| 72 | + |
| 73 | +1. Generates a new session ID. |
| 74 | +2. Initializes the code checkpoint branch for that session. |
| 75 | +3. Adds an entry to `sessions-index.json`. |
| 76 | +4. Writes system prompts, runtime context, project instructions, and the user message. |
| 77 | +5. Starts the model request and keeps updating the index and message file as assistant replies and tool executions complete. |
| 78 | + |
| 79 | +The per-project session list keeps the 50 most recent entries. When the limit is exceeded, older sessions are removed from the index, and their message files and related runtime resources are cleaned up. |
| 80 | + |
| 81 | +### Continuing A Session |
| 82 | + |
| 83 | +`/resume` shows the current project's session history and lets you select a session to continue. |
| 84 | + |
| 85 | +`/continue` first continues the active session. If there is no active session to continue, it opens the session selection flow. |
| 86 | + |
| 87 | +When continuing a session, Deep Code reads the message file, filters compacted old messages, repairs incomplete tool-call context, and converts the usable history into model request messages. |
| 88 | + |
| 89 | +### Long-Session Compaction |
| 90 | + |
| 91 | +When the conversation context grows too large, Deep Code can compact earlier messages: |
| 92 | + |
| 93 | +- It summarizes an older range of non-system messages. |
| 94 | +- It marks those old messages as `compacted: true`. |
| 95 | +- It inserts an invisible system summary message into the message sequence. |
| 96 | + |
| 97 | +Future requests use the remaining active messages and the summary message. The original messages stay in the JSONL file for auditability and UI history. |
| 98 | + |
| 99 | +### Interruptions, Failures, And Permission Waits |
| 100 | + |
| 101 | +Session status changes during execution: |
| 102 | + |
| 103 | +- After a user interruption, status becomes `interrupted`, and Deep Code clears the current session controller and tracked subprocesses. |
| 104 | +- After a request failure, status becomes `failed`, and the failure reason is written to the index. |
| 105 | +- When a tool call needs confirmation, status becomes `ask_permission`. |
| 106 | +- When a tool needs user input, status becomes `waiting_for_user`. |
| 107 | + |
| 108 | +These states are persisted in `sessions-index.json`, so they remain visible in the session list after reopening the CLI. |
| 109 | + |
| 110 | +## How `/undo` Uses Persistent Data |
| 111 | + |
| 112 | +`/undo` candidates come from visible, non-compacted user messages. Each candidate is checked for an associated `checkpointHash`, and Deep Code verifies whether the checkpoint can be restored. |
| 113 | + |
| 114 | +Depending on the selected mode, Deep Code can perform these operations: |
| 115 | + |
| 116 | +| Operation | Behavior | |
| 117 | +| --------- | -------- | |
| 118 | +| Restore conversation | Truncates message history before the selected user message and updates the latest assistant data in the index. | |
| 119 | +| Restore code | Reads the selected checkpoint from `file-history/.git` and restores tracked files. | |
| 120 | +| Restore both | Restores code first, then truncates the conversation history. | |
| 121 | + |
| 122 | +Restoring conversation rewrites the session JSONL file. Restoring code modifies workspace files tracked by the selected checkpoint. |
| 123 | + |
| 124 | +## Delete And Rename |
| 125 | + |
| 126 | +Deleting a session from the session list: |
| 127 | + |
| 128 | +- Removes the entry from `sessions-index.json`. |
| 129 | +- Deletes the matching `<session-id>.jsonl` file. |
| 130 | +- Clears in-memory state, temporary working-directory state, controllers, and tracked process controls for that session. |
| 131 | + |
| 132 | +Renaming a session only updates the `summary` field in the index. It does not change message files or code checkpoints. |
| 133 | + |
| 134 | +## Notes |
| 135 | + |
| 136 | +- Session data is stored in the local user directory and separated by project. |
| 137 | +- If a project directory is moved, the new project root path generates a new `<project-code>`; history for the old path is not migrated automatically. |
| 138 | +- `file-history/.git` is Deep Code's internal checkpoint repository and should not be edited manually. |
| 139 | +- Deleting a session does not remove every historical object from the internal Git repository. It mainly removes the session index entry, message file, and runtime resources. |
0 commit comments