refactor: restructure project to monorepo with apps directory

This commit is contained in:
Cody Seibert
2025-12-11 20:34:49 -05:00
parent 7cb5a6a4df
commit 1bb20e5070
164 changed files with 12215 additions and 14 deletions

View File

@@ -0,0 +1,285 @@
# Agent Architecture - Surviving Next.js Restarts
## Problem Statement
When using the Automaker app to iterate on itself:
1. Agent modifies code files
2. Next.js hot-reloads and restarts
3. API routes are killed
4. Agent conversation is lost
## Solution: Electron Main Process Agent
The agent now runs in the **Electron main process** instead of Next.js API routes. This provides:
-**Survives Next.js restarts** - Main process is independent of renderer
-**Persistent state** - Conversations saved to disk automatically
-**Real-time streaming** - IPC events for live updates
-**Session recovery** - Reconnects automatically after restart
## Architecture Overview
```
┌─────────────────────────────────────────┐
│ Electron Main Process │
│ ┌───────────────────────────────┐ │
│ │ Agent Service │ │
│ │ - Manages sessions │ │
│ │ - Runs Claude Agent SDK │ │
│ │ - Persists to disk │ │
│ │ - Streams via IPC │ │
│ └───────────────────────────────┘ │
└──────────────┬──────────────────────────┘
│ IPC (survives restarts)
┌──────────────┴──────────────────────────┐
│ Electron Renderer (Next.js) │
│ ┌───────────────────────────────┐ │
│ │ React Frontend │ │
│ │ - useElectronAgent hook │ │
│ │ - Auto-reconnects │ │
│ │ - Real-time updates │ │
│ └───────────────────────────────┘ │
└─────────────────────────────────────────┘
```
## Key Components
### 1. Agent Service (`electron/agent-service.js`)
The core service running in the Electron main process:
- **Session Management**: Tracks multiple conversations by session ID
- **State Persistence**: Saves conversations to `userData/agent-sessions/*.json`
- **Streaming**: Sends real-time updates to renderer via IPC
- **Tool Support**: Full Read/Write/Edit/Bash/Grep/Glob capabilities
- **Error Recovery**: Continues after errors, saves state
### 2. IPC Handlers (`electron/main.js`)
Electron main process handlers:
- `agent:start` - Initialize or resume a session
- `agent:send` - Send a message (returns immediately)
- `agent:getHistory` - Retrieve conversation history
- `agent:stop` - Stop current execution
- `agent:clear` - Clear conversation
- `agent:stream` - Event emitted for streaming updates
### 3. Preload Bridge (`electron/preload.js`)
Secure IPC bridge exposed to renderer:
```javascript
window.electronAPI.agent.start(sessionId, workingDir);
window.electronAPI.agent.send(sessionId, message, workingDir);
window.electronAPI.agent.onStream(callback);
```
### 4. React Hook (`src/hooks/use-electron-agent.ts`)
Easy-to-use React hook:
```typescript
const {
messages, // Conversation history
isProcessing, // Agent is working
isConnected, // Session initialized
sendMessage, // Send user message
stopExecution, // Stop current task
clearHistory, // Clear conversation
error, // Error state
} = useElectronAgent({
sessionId: "project_xyz",
workingDirectory: "/path/to/project",
onToolUse: (tool) => console.log("Using:", tool),
});
```
### 5. Frontend Component (`src/components/views/agent-view.tsx`)
Updated to use IPC instead of HTTP:
- Generates session ID from project path
- Auto-reconnects on mount
- Shows tool usage in real-time
- Displays connection status
## Data Flow
### Sending a Message
1. User types message in React UI
2. `sendMessage()` calls `window.electronAPI.agent.send()`
3. IPC handler in main process receives message
4. Agent service starts processing
5. Main process streams updates via `agent:stream` events
6. React hook receives events and updates UI
7. Conversation saved to disk
### Surviving a Restart
1. Agent is modifying code → Next.js restarts
2. React component unmounts
3. **Main process keeps running** (agent continues)
4. React component remounts after restart
5. Calls `agent:start` with same session ID
6. Main process returns full conversation history
7. Subscribes to `agent:stream` events
8. UI shows complete conversation + live updates
## Session Storage
Sessions are stored in:
```
<userData>/agent-sessions/<sessionId>.json
```
Each session file contains:
```json
[
{
"id": "msg_1234_abc",
"role": "user",
"content": "Add a new feature...",
"timestamp": "2024-12-07T12:00:00.000Z"
},
{
"id": "msg_1235_def",
"role": "assistant",
"content": "I'll help you add that feature...",
"timestamp": "2024-12-07T12:00:05.000Z"
}
]
```
## Session ID Generation
Session IDs are generated from project paths:
```typescript
const sessionId = `project_${projectPath.replace(/[^a-zA-Z0-9]/g, "_")}`;
```
This ensures:
- Each project has its own conversation
- Conversations persist across app restarts
- Multiple projects can run simultaneously
## Streaming Events
The agent emits these event types:
### `message`
User message added to conversation
### `stream`
Assistant response streaming (updates in real-time)
### `tool_use`
Agent is using a tool (Read, Write, Edit, etc.)
### `complete`
Agent finished processing
### `error`
Error occurred during processing
## Configuration
The agent is configured with:
```javascript
{
model: "claude-opus-4-5-20251101",
maxTurns: 20,
cwd: workingDirectory,
allowedTools: [
"Read", "Write", "Edit", "Glob", "Grep",
"Bash", "WebSearch", "WebFetch"
],
permissionMode: "acceptEdits", // Auto-approve file edits
sandbox: {
enabled: true, // Sandboxed bash execution
autoAllowBashIfSandboxed: true
}
}
```
## Benefits
### For Self-Iteration
Now you can ask the agent to modify Automaker itself:
```
User: "Add a dark mode toggle to the settings"
Agent: *modifies files*
→ Next.js restarts
→ Agent continues working
→ UI reconnects automatically
→ Shows full conversation history
```
### For Long-Running Tasks
The agent can work on complex tasks that take multiple turns:
```
User: "Implement authentication with GitHub OAuth"
Agent:
1. Creates auth API routes
2. Next.js restarts
3. Agent continues: Adds middleware
4. Next.js restarts again
5. Agent continues: Updates UI components
6. All changes tracked, conversation preserved
```
## Testing
To test the architecture:
1. Open a project in Automaker
2. Ask the agent to modify a file in `src/`
3. Watch Next.js restart
4. Verify the conversation continues
5. Check that history is preserved
6. Restart the entire Electron app
7. Verify conversation loads from disk
## Troubleshooting
### "Electron API not available"
- Make sure you're running in Electron, not browser
- Check `window.isElectron` is `true`
### Session not persisting
- Check userData directory exists
- Verify write permissions
- Look for errors in Electron console
### Next.js restart kills agent
- Verify agent service is in `electron/main.js`
- Check IPC handlers are registered
- Ensure not using HTTP `/api/chat` route
## Future Enhancements
- [ ] Multiple concurrent sessions
- [ ] Export conversation history
- [ ] Undo/redo for agent actions
- [ ] Progress bars for long-running tasks
- [ ] Voice input/output
- [ ] Agent memory across sessions

View File

@@ -0,0 +1,375 @@
# Session Management Guide
## Overview
The Automaker Agent Chat now supports multiple concurrent sessions, allowing you to organize different conversations by topic, feature, or task. Each session is independently managed and persisted.
## Features
### ✨ Multiple Sessions
- Create unlimited agent sessions per project
- Each session has its own conversation history
- Switch between sessions instantly
- Sessions persist across app restarts
### 📋 Session Organization
- Custom names for easy identification
- Last message preview
- Message count tracking
- Sort by most recently updated
### 🗄️ Archive & Delete
- Archive old sessions to declutter
- Unarchive when needed
- Permanently delete sessions
- Confirm before destructive actions
### 💾 Automatic Persistence
- All sessions auto-save to disk
- Survive Next.js restarts
- Survive Electron app restarts
- Never lose your conversations
## User Interface
### Session Manager Sidebar
Located on the left side of the Agent Chat view:
```
┌──────────────────────────┬────────────────────────┐
│ Session Manager │ Chat Messages │
│ │ │
│ [+ New] [Archive] │ User: Hello │
│ │ Agent: Hi there! │
│ 📝 Feature: Auth │ │
│ "Add OAuth login..." │ [Input field] │
│ 42 messages │ │
│ │ │
│ 📝 Bug: Payment │ │
│ "Fix stripe inte..." │ │
│ 15 messages │ │
│ │ │
└──────────────────────────┴────────────────────────┘
```
### Toggle Sidebar
Click the panel icon in the header to show/hide the session manager.
## How to Use
### Creating a Session
1. Click the **"+ New"** button
2. Enter a descriptive name
3. Press Enter or click ✓
4. The new session is immediately active
**Example session names:**
- "Feature: Dark Mode"
- "Bug: Login redirect"
- "Refactor: API layer"
- "Docs: Getting started"
### Switching Sessions
Simply click on any session in the list to switch to it. The conversation history loads instantly.
### Renaming a Session
1. Click the edit icon (✏️) next to the session name
2. Type the new name
3. Press Enter or click ✓
### Clearing a Session
Click the **"Clear"** button in the chat header to delete all messages from the current session while keeping the session itself.
### Archiving a Session
1. Click the archive icon (📦) next to the session
2. The session moves to the archived list
3. Toggle **"Show Archived"** to view archived sessions
**When to archive:**
- Completed features
- Resolved bugs
- Old experiments
- Historical reference
### Unarchiving a Session
1. Toggle **"Show Archived"** to see archived sessions
2. Click the unarchive icon (📤)
3. The session returns to the active list
### Deleting a Session
1. Archive the session first
2. View archived sessions
3. Click the delete icon (🗑️)
4. Confirm the deletion
5. **This is permanent!**
## Storage Location
Sessions are stored in your user data directory:
**macOS:**
```
~/Library/Application Support/automaker/agent-sessions/
```
**Windows:**
```
%APPDATA%/automaker/agent-sessions/
```
**Linux:**
```
~/.config/automaker/agent-sessions/
```
### File Structure
```
agent-sessions/
├── session_1234567890_abc.json # Session conversation
├── session_1234567891_def.json # Another session
└── sessions-metadata.json # Session metadata
```
### Session File Format
Each session file contains an array of messages:
```json
[
{
"id": "msg_1234567890_xyz",
"role": "user",
"content": "Add authentication to the app",
"timestamp": "2024-12-07T12:00:00.000Z"
},
{
"id": "msg_1234567891_abc",
"role": "assistant",
"content": "I'll help you add authentication...",
"timestamp": "2024-12-07T12:00:05.000Z"
}
]
```
### Metadata File Format
The metadata file tracks all sessions:
```json
{
"session_1234567890_abc": {
"name": "Feature: Authentication",
"projectPath": "/path/to/project",
"createdAt": "2024-12-07T12:00:00.000Z",
"updatedAt": "2024-12-07T12:30:00.000Z",
"isArchived": false,
"tags": []
}
}
```
## Best Practices
### Naming Conventions
Use prefixes to organize sessions by type:
- **Feature:** New functionality
- "Feature: Dark mode toggle"
- "Feature: User profiles"
- **Bug:** Issue resolution
- "Bug: Memory leak in dashboard"
- "Bug: Form validation errors"
- **Refactor:** Code improvements
- "Refactor: Database layer"
- "Refactor: Component structure"
- **Docs:** Documentation work
- "Docs: API documentation"
- "Docs: README updates"
- **Experiment:** Try new ideas
- "Experiment: WebGL renderer"
- "Experiment: New state management"
### Session Lifecycle
1. **Create** → Start a new feature or task
2. **Work** → Have conversation, iterate on code
3. **Complete** → Finish the task
4. **Archive** → Keep for reference
5. **Delete** → Remove when no longer needed
### When to Create Multiple Sessions
**Do create separate sessions for:**
- ✅ Different features
- ✅ Unrelated bugs
- ✅ Experimental work
- ✅ Different contexts or approaches
**Don't create separate sessions for:**
- ❌ Same feature, different iterations
- ❌ Related bug fixes
- ❌ Continuation of previous work
### Managing Session Clutter
- Archive completed work weekly
- Delete archived sessions after 30 days
- Use clear naming conventions
- Consolidate related sessions
## Integration with Project Workflow
### Feature Development
```
1. Create: "Feature: User notifications"
2. Agent: Design the notification system
3. Agent: Implement backend
4. Next.js restarts (agent continues)
5. Agent: Implement frontend
6. Agent: Add tests
7. Complete & Archive
```
### Bug Fixing
```
1. Create: "Bug: Payment processing timeout"
2. Agent: Investigate the issue
3. Agent: Identify root cause
4. Agent: Implement fix
5. Agent: Add regression test
6. Complete & Archive
```
### Refactoring
```
1. Create: "Refactor: API error handling"
2. Agent: Analyze current implementation
3. Agent: Design new approach
4. Agent: Refactor service layer
5. Next.js restarts (agent continues)
6. Agent: Refactor controller layer
7. Agent: Update tests
8. Complete & Archive
```
## Keyboard Shortcuts
*(Coming soon)*
- `Cmd/Ctrl + K` - Create new session
- `Cmd/Ctrl + [` - Previous session
- `Cmd/Ctrl + ]` - Next session
- `Cmd/Ctrl + Shift + A` - Toggle archive view
## Troubleshooting
### Session Not Saving
**Check:**
- Electron has write permissions
- Disk space available
- Check Electron console for errors
**Solution:**
```bash
# macOS - Check permissions
ls -la ~/Library/Application\ Support/automaker/
# Fix permissions if needed
chmod -R u+w ~/Library/Application\ Support/automaker/
```
### Can't Switch Sessions
**Check:**
- Session is not archived
- No errors in console
- Agent is not currently processing
**Solution:**
- Wait for current message to complete
- Check for error messages
- Try clearing and reloading
### Session Disappeared
**Check:**
- Not filtered by archive status
- Not accidentally deleted
- Check backup files
**Recovery:**
- Toggle "Show Archived"
- Check filesystem for `.json` files
- Restore from backup if available
## API Reference
For developers integrating session management:
### Create Session
```typescript
const result = await window.electronAPI.sessions.create(
"Session Name",
"/project/path",
"/working/directory"
);
```
### List Sessions
```typescript
const { sessions } = await window.electronAPI.sessions.list(
false // includeArchived
);
```
### Update Session
```typescript
await window.electronAPI.sessions.update(
sessionId,
"New Name",
["tag1", "tag2"]
);
```
### Archive/Unarchive
```typescript
await window.electronAPI.sessions.archive(sessionId);
await window.electronAPI.sessions.unarchive(sessionId);
```
### Delete Session
```typescript
await window.electronAPI.sessions.delete(sessionId);
```
## Future Enhancements
- [ ] Tag system for categorization
- [ ] Search sessions by content
- [ ] Export session to markdown
- [ ] Share sessions with team
- [ ] Session templates
- [ ] Keyboard shortcuts
- [ ] Drag & drop to reorder
- [ ] Favorite/pin sessions
- [ ] Session statistics
- [ ] Automatic archiving rules