Skip to content

Commit 40785dd

Browse files
committed
implemented autosave chat caching in .ti folder
1 parent 68c6c8f commit 40785dd

14 files changed

Lines changed: 1148 additions & 161 deletions

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Quick overview of current menu shotcuts and key combinations
2020
- **Code Editor**: Syntax-aware text editing with line numbers and file type detection
2121
- **AI Integration**: Context-aware AI assistance powered by Ollama, Gemini, or AWS Bedrock
2222
- **Agentic Code Fixing**: AI autonomously reads, analyzes, and fixes code directly in the editor
23-
- **Chat History Management**: Save and reload complete AI conversations with Ctrl+A and Ctrl+L
23+
- **Chat History Management**: Automatic session saving and reload with Ctrl+L
2424
- **Integrated Git Operations**: Full Git workflow support with visual panel interface
2525
- **File Management**: Create, open, save, and delete files
2626
- **Command Execution**: Run scripts and programs with Ctrl+R (auto-detects file type)

docs/AUTO_CHAT_SESSION_SAVE.md

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
# Automatic Chat Session Save Implementation
2+
3+
## Overview
4+
5+
The application now automatically saves all AI chat conversations to session files in the `.ti/` directory. This eliminates the need for manual save operations (like Ctrl+A) and ensures no conversation history is lost.
6+
7+
## How It Works
8+
9+
### Automatic Session Creation
10+
11+
1. When the first message is sent in a new chat session, a session file is automatically created
12+
2. The file is named: `session_token_chat_YYYYMMDD_HHMMSS.md`
13+
- Example: `session_token_chat_20260305_143045.md`
14+
3. The timestamp reflects when the session started
15+
16+
### Real-Time Message Saving
17+
18+
Every message (user and assistant) is immediately appended to the session file as it's sent or received:
19+
20+
- User messages are saved when sent
21+
- Assistant responses are saved when received
22+
- Fix requests are saved with context
23+
- Notifications are saved
24+
25+
### Session Lifecycle
26+
27+
- **New Session**: Created on first message after app start or after clearing chat (Ctrl+T)
28+
- **Active Session**: All subsequent messages append to the same file
29+
- **Session End**: When chat is cleared (Ctrl+T), the session file is finalized and a new one will be created for the next conversation
30+
31+
## Implementation Details
32+
33+
### Core Function: `appendMessageToSessionLog`
34+
35+
Located in `internal/ui/aichat.go`:
36+
37+
```go
38+
func (a *AIChatPane) appendMessageToSessionLog(msg types.ChatMessage) {
39+
if a.workspaceRoot == "" {
40+
return
41+
}
42+
43+
tiDir := filepath.Join(a.workspaceRoot, ".ti")
44+
tiDirCreated := false
45+
if _, err := os.Stat(tiDir); os.IsNotExist(err) {
46+
os.MkdirAll(tiDir, 0755)
47+
tiDirCreated = true
48+
}
49+
50+
// If we just created .ti/ directory, ensure it's in .gitignore
51+
if tiDirCreated {
52+
a.ensureTiDirInGitignore()
53+
}
54+
55+
if a.sessionFile == "" {
56+
a.sessionFile = filepath.Join(tiDir, fmt.Sprintf("session_token_chat_%s.md", time.Now().Format("20060102_150405")))
57+
}
58+
59+
f, err := os.OpenFile(a.sessionFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
60+
if err != nil {
61+
return
62+
}
63+
defer f.Close()
64+
65+
var content strings.Builder
66+
content.WriteString(msg.Role)
67+
content.WriteString(" ")
68+
content.WriteString(msg.Timestamp.Format("15:04:05"))
69+
content.WriteString("\n")
70+
content.WriteString(msg.Content)
71+
content.WriteString("\n\n")
72+
73+
f.WriteString(content.String())
74+
}
75+
```
76+
77+
### Automatic .gitignore Management: `ensureTiDirInGitignore`
78+
79+
Also located in `internal/ui/aichat.go`:
80+
81+
```go
82+
func (a *AIChatPane) ensureTiDirInGitignore() {
83+
if a.workspaceRoot == "" {
84+
return
85+
}
86+
87+
gitignorePath := filepath.Join(a.workspaceRoot, ".gitignore")
88+
89+
// Read existing .gitignore if it exists
90+
content, err := os.ReadFile(gitignorePath)
91+
if err != nil && !os.IsNotExist(err) {
92+
return
93+
}
94+
95+
contentStr := string(content)
96+
97+
// Check if .ti/ is already in .gitignore
98+
lines := strings.Split(contentStr, "\n")
99+
for _, line := range lines {
100+
trimmed := strings.TrimSpace(line)
101+
if trimmed == ".ti/" || trimmed == ".ti" || trimmed == "/.ti/" {
102+
return // Already present
103+
}
104+
}
105+
106+
// Need to add .ti/ to .gitignore
107+
var newContent string
108+
if contentStr == "" {
109+
newContent = ".ti/\n"
110+
} else {
111+
if !strings.HasSuffix(contentStr, "\n") {
112+
newContent = contentStr + "\n.ti/\n"
113+
} else {
114+
newContent = contentStr + ".ti/\n"
115+
}
116+
}
117+
118+
os.WriteFile(gitignorePath, []byte(newContent), 0644)
119+
}
120+
```
121+
122+
### Integration Points
123+
124+
The function is called from:
125+
126+
1. `SendMessage()` - When user sends a message
127+
2. `DisplayResponse()` - When AI responds
128+
3. `DisplayNotification()` - When notifications are shown
129+
4. `AddFixRequest()` - When fix requests are added
130+
131+
### File Format
132+
133+
Each message is saved in this format:
134+
135+
```markdown
136+
role timestamp
137+
content
138+
139+
role timestamp
140+
content
141+
```
142+
143+
Example:
144+
145+
```markdown
146+
user 14:30:45
147+
How do I create a web server in Go?
148+
149+
assistant 14:30:52
150+
To create a web server in Go, you can use the net/http package...
151+
152+
user 14:32:10
153+
Can you add routing?
154+
155+
assistant 14:32:18
156+
Sure! Here's how to add routing...
157+
```
158+
159+
## Loading Saved Sessions
160+
161+
Users can reload any saved session using Ctrl+L:
162+
163+
1. Press Ctrl+L to open the chat loader
164+
2. Select from a list of saved sessions (newest first)
165+
3. Press Enter to load the selected session
166+
4. The entire conversation history is restored
167+
168+
The chat loader specifically looks for files matching the pattern: `session_token_chat_*.md`
169+
170+
## Benefits
171+
172+
1. **No Data Loss**: Conversations are saved in real-time
173+
2. **No Manual Action**: Users don't need to remember to save
174+
3. **Session Organization**: Each conversation gets its own file
175+
4. **Easy Recovery**: Load any previous session with Ctrl+L
176+
5. **Searchable**: Files are in markdown format for easy searching
177+
6. **Timestamped**: Both filename and messages include timestamps
178+
7. **Git-Safe**: Automatic `.gitignore` management prevents accidental commits
179+
180+
## Testing
181+
182+
Comprehensive tests are included in `internal/ui/session_log_test.go`:
183+
184+
### Session Logging Tests
185+
- `TestAppendMessageToSessionLog`: Verifies messages are saved correctly
186+
- `TestSessionFileReusedAcrossMessages`: Ensures same file is used for entire session
187+
- `TestSessionFileResetOnClearHistory`: Confirms new session starts after clearing
188+
- `TestNoSessionFileWithoutWorkspaceRoot`: Handles edge case of no workspace
189+
190+
### .gitignore Management Tests
191+
- `TestEnsureTiDirInGitignore_NewGitignore`: Creates new .gitignore with .ti/ entry
192+
- `TestEnsureTiDirInGitignore_ExistingGitignore`: Appends to existing .gitignore
193+
- `TestEnsureTiDirInGitignore_AlreadyPresent`: Avoids duplicate entries
194+
- `TestEnsureTiDirInGitignore_VariantFormats`: Handles .ti, .ti/, /.ti/ variants
195+
- `TestEnsureTiDirInGitignore_NoWorkspaceRoot`: Gracefully handles missing workspace
196+
- `TestEnsureTiDirInGitignore_OnlyOnFirstCreation`: Ensures .gitignore is only updated once
197+
198+
All tests pass successfully.
199+
200+
## Migration from Manual Save
201+
202+
Previously, the documentation mentioned Ctrl+A for manual saving. This has been removed because:
203+
204+
1. Automatic saving is more reliable
205+
2. No user action required
206+
3. Real-time saving prevents data loss
207+
4. Simpler user experience
208+
209+
The documentation has been updated to reflect the automatic saving behavior.
210+
211+
## File Location
212+
213+
All session files are stored in:
214+
```
215+
<workspace-root>/.ti/session_token_chat_*.md
216+
```
217+
218+
The `.ti` directory is automatically created if it doesn't exist.
219+
220+
## Edge Cases Handled
221+
222+
1. **No Workspace Root**: If `workspaceRoot` is empty, no session file is created (graceful degradation)
223+
2. **Directory Creation**: The `.ti` directory is created automatically if needed
224+
3. **File Errors**: File write errors are silently ignored to prevent disrupting the user experience
225+
4. **Session Reset**: Clearing chat (Ctrl+T) resets the session file path, so a new file is created for the next conversation
226+
5. **Duplicate .gitignore Entries**: Checks for `.ti/`, `.ti`, and `/.ti/` variants to avoid duplicates
227+
6. **Existing .gitignore**: Preserves existing content when appending `.ti/`
228+
7. **Missing .gitignore**: Creates new `.gitignore` file if it doesn't exist
229+
8. **Multiple Messages**: `.gitignore` is only updated once when `.ti/` directory is first created
230+
231+
## Future Enhancements
232+
233+
Potential improvements:
234+
235+
1. Session file size limits (split large sessions)
236+
2. Automatic cleanup of old sessions
237+
3. Session search/filter functionality
238+
4. Export sessions to different formats
239+
5. Session tagging or categorization

docs/CHAT_LOADER_IMPLEMENTATION.md

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Chat Loader Implementation Summary
22

33
## Overview
4-
Implemented Ctrl+L functionality to load previously saved chat histories back into the AI pane, complementing the existing Ctrl+A save feature.
4+
Implemented Ctrl+L functionality to load previously saved chat histories back into the AI pane. Chat sessions are automatically saved in real-time, eliminating the need for manual save operations.
55

66
## Implementation Details
77

@@ -58,9 +58,11 @@ content
5858

5959
Updated the AI pane title bar to show:
6060
```
61-
AI Responses (02) [Gemini] | Ctrl+Y: Code | Ctrl+A: Save | Ctrl+L: Load | ↑↓: Scroll | Ctrl+T: New
61+
AI Responses (02) [Gemini] | Ctrl+Y: Code | Ctrl+L: Load | ↑↓: Scroll | Ctrl+T: New
6262
```
6363

64+
Note: Chat sessions are now automatically saved in real-time, so manual save is no longer needed.
65+
6466
### 7. Help System Updates
6567

6668
Updated help text in:
@@ -70,11 +72,11 @@ Updated help text in:
7072

7173
## User Workflow
7274

73-
### Saving a Chat
74-
1. User has conversation with AI
75-
2. Presses `Ctrl+A`
76-
3. Chat saved to `.ti/chat-YYYY-MM-DD-HH-MM-SS-query.md`
77-
4. File opens in editor
75+
### Automatic Chat Saving
76+
1. User starts conversation with AI
77+
2. First message automatically creates a session file: `.ti/session_token_chat_YYYYMMDD_HHMMSS.md`
78+
3. All subsequent messages are automatically appended to the same file
79+
4. No manual action required - everything is saved in real-time
7880

7981
### Loading a Chat
8082
1. User presses `Ctrl+L` (works anytime, especially after `Ctrl+T` clear)

docs/CHAT_SAVE_FEATURE.md

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,25 @@
11
# Chat Save Feature
22

33
## Overview
4-
The Ctrl+A shortcut saves the entire AI chat history to a markdown file in the `.ti/` folder. The Ctrl+L shortcut allows you to reload previously saved chats back into the AI pane.
4+
Chat conversations are automatically saved to markdown files in the `.ti/` folder as you interact with the AI. The Ctrl+L shortcut allows you to reload previously saved chats back into the AI pane.
55

6-
## Save Chat (Ctrl+A)
6+
## Automatic Chat Saving
77

8-
### Usage
8+
### How It Works
9+
10+
1. When you start a conversation with the AI assistant, a new session file is automatically created
11+
2. Every message (both user and assistant) is immediately appended to the session file
12+
3. The session file is named `.ti/session_token_chat_YYYYMMDD_HHMMSS.md` based on when the session started
13+
4. All messages in the current session are saved to the same file
14+
5. When you clear chat history (Ctrl+T), a new session file will be created for the next conversation
15+
16+
### Automatic .gitignore Management
917

10-
1. Have a conversation with the AI assistant
11-
2. Press `Ctrl+A` at any time during or after the conversation
12-
3. The entire chat history will be automatically saved to `.ti/chat-YYYY-MM-DD-HH-MM-SS-query.md`
13-
4. The saved file will automatically open in the editor
18+
When the `.ti/` directory is created for the first time:
19+
- If `.gitignore` exists: `.ti/` is automatically appended to it
20+
- If `.gitignore` doesn't exist: A new `.gitignore` file is created with `.ti/` entry
21+
- The system checks for existing `.ti/`, `.ti`, or `/.ti/` entries to avoid duplicates
22+
- This ensures your chat sessions are never accidentally committed to version control
1423

1524
### File Format
1625

@@ -32,12 +41,20 @@ Sure! I'll add network statistics to the program...
3241

3342
### Filename Convention
3443

35-
The filename is generated automatically using:
36-
- Current date: `YYYY-MM-DD`
37-
- First user message timestamp: `HH-MM-SS`
38-
- First few words of the user's initial query (sanitized for filename compatibility)
44+
The filename is generated automatically when the first message is sent:
45+
- Format: `session_token_chat_YYYYMMDD_HHMMSS.md`
46+
- Date: `YYYYMMDD` (e.g., 20260305)
47+
- Time: `HHMMSS` (e.g., 143045)
3948

40-
Example: `chat-2026-02-26-13-32-48-using-Go-language-create-a-program.md`
49+
Example: `session_token_chat_20260305_143045.md`
50+
51+
### Benefits of Automatic Saving
52+
53+
- No manual action required - conversations are preserved automatically
54+
- Real-time saving - messages are saved immediately as they're sent/received
55+
- No risk of losing conversation history
56+
- Eliminates the need for manual Ctrl+A save operations
57+
- Session-based organization - each conversation session gets its own file
4158

4259
## Load Chat (Ctrl+L)
4360

@@ -70,17 +87,22 @@ All chat files are saved in the `.ti/` directory at the workspace root:
7087
```
7188
<workspace-root>/
7289
.ti/
73-
chat-2026-02-26-13-32-48-query1.md
74-
chat-2026-02-26-14-15-30-query2.md
90+
session_token_chat_20260305_143045.md
91+
session_token_chat_20260305_151230.md
7592
20260219-160311_test.py (existing backup files)
93+
.gitignore (automatically updated to include .ti/)
7694
```
7795

78-
## Benefits
96+
The `.ti/` directory is automatically added to `.gitignore` to prevent chat sessions from being committed to version control.
97+
98+
## Overall Benefits
7999

80-
- Complete conversation history preserved
100+
- Complete conversation history preserved automatically
101+
- Real-time saving - no data loss
81102
- Timestamped for easy reference
82103
- Searchable markdown format
83104
- Automatic organization in `.ti/` folder
84-
- No manual filename prompts
105+
- No manual save operations required
85106
- Easy to reload and continue conversations
86-
- Instantly viewable in the editor
107+
- Session-based file organization
108+
- Automatic `.gitignore` management - chat sessions never committed to Git

0 commit comments

Comments
 (0)