Files
automaker/app/electron/preload.js
Kacper a78b6763de feat(core): implement git worktree checkpoint system
Add comprehensive worktree management system to enable task isolation and rollback capabilities. This allows users to revert agent changes if they don't satisfy requirements or break functionality.

Key components:
- New WorktreeManager service for branch and worktree operations
- GitDiffPanel component for visualizing changes
- Enhanced UI components with worktree integration
- Auto-mode service enhancements for worktree workflow

Modified files: worktree-manager.js, git-diff-panel.tsx, main.js, preload.js, feature-loader.js, agent-output-modal.tsx, board-view.tsx, kanban-card.tsx, electron.ts, app-store.ts, electron.d.ts

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
2025-12-10 12:28:13 +01:00

196 lines
7.0 KiB
JavaScript

const { contextBridge, ipcRenderer } = require("electron");
// Expose protected methods that allow the renderer process to use
// the ipcRenderer without exposing the entire object
contextBridge.exposeInMainWorld("electronAPI", {
// IPC test
ping: () => ipcRenderer.invoke("ping"),
// Dialog APIs
openDirectory: () => ipcRenderer.invoke("dialog:openDirectory"),
openFile: (options) => ipcRenderer.invoke("dialog:openFile", options),
// File system APIs
readFile: (filePath) => ipcRenderer.invoke("fs:readFile", filePath),
writeFile: (filePath, content) =>
ipcRenderer.invoke("fs:writeFile", filePath, content),
mkdir: (dirPath) => ipcRenderer.invoke("fs:mkdir", dirPath),
readdir: (dirPath) => ipcRenderer.invoke("fs:readdir", dirPath),
exists: (filePath) => ipcRenderer.invoke("fs:exists", filePath),
stat: (filePath) => ipcRenderer.invoke("fs:stat", filePath),
deleteFile: (filePath) => ipcRenderer.invoke("fs:deleteFile", filePath),
trashItem: (filePath) => ipcRenderer.invoke("fs:trashItem", filePath),
// App APIs
getPath: (name) => ipcRenderer.invoke("app:getPath", name),
saveImageToTemp: (data, filename, mimeType) =>
ipcRenderer.invoke("app:saveImageToTemp", { data, filename, mimeType }),
// Agent APIs
agent: {
// Start or resume a conversation
start: (sessionId, workingDirectory) =>
ipcRenderer.invoke("agent:start", { sessionId, workingDirectory }),
// Send a message to the agent
send: (sessionId, message, workingDirectory, imagePaths) =>
ipcRenderer.invoke("agent:send", { sessionId, message, workingDirectory, imagePaths }),
// Get conversation history
getHistory: (sessionId) =>
ipcRenderer.invoke("agent:getHistory", { sessionId }),
// Stop current execution
stop: (sessionId) =>
ipcRenderer.invoke("agent:stop", { sessionId }),
// Clear conversation
clear: (sessionId) =>
ipcRenderer.invoke("agent:clear", { sessionId }),
// Subscribe to streaming events
onStream: (callback) => {
const subscription = (_, data) => callback(data);
ipcRenderer.on("agent:stream", subscription);
// Return unsubscribe function
return () => ipcRenderer.removeListener("agent:stream", subscription);
},
},
// Session Management APIs
sessions: {
// List all sessions
list: (includeArchived) =>
ipcRenderer.invoke("sessions:list", { includeArchived }),
// Create a new session
create: (name, projectPath, workingDirectory) =>
ipcRenderer.invoke("sessions:create", { name, projectPath, workingDirectory }),
// Update session metadata
update: (sessionId, name, tags) =>
ipcRenderer.invoke("sessions:update", { sessionId, name, tags }),
// Archive a session
archive: (sessionId) =>
ipcRenderer.invoke("sessions:archive", { sessionId }),
// Unarchive a session
unarchive: (sessionId) =>
ipcRenderer.invoke("sessions:unarchive", { sessionId }),
// Delete a session permanently
delete: (sessionId) =>
ipcRenderer.invoke("sessions:delete", { sessionId }),
},
// Auto Mode API
autoMode: {
// Start auto mode
start: (projectPath, maxConcurrency) =>
ipcRenderer.invoke("auto-mode:start", { projectPath, maxConcurrency }),
// Stop auto mode
stop: () => ipcRenderer.invoke("auto-mode:stop"),
// Get auto mode status
status: () => ipcRenderer.invoke("auto-mode:status"),
// Run a specific feature
runFeature: (projectPath, featureId) =>
ipcRenderer.invoke("auto-mode:run-feature", { projectPath, featureId }),
// Verify a specific feature by running its tests
verifyFeature: (projectPath, featureId) =>
ipcRenderer.invoke("auto-mode:verify-feature", { projectPath, featureId }),
// Resume a specific feature with previous context
resumeFeature: (projectPath, featureId) =>
ipcRenderer.invoke("auto-mode:resume-feature", { projectPath, featureId }),
// Check if context file exists for a feature
contextExists: (projectPath, featureId) =>
ipcRenderer.invoke("auto-mode:context-exists", { projectPath, featureId }),
// Analyze a new project - kicks off an agent to analyze codebase
analyzeProject: (projectPath) =>
ipcRenderer.invoke("auto-mode:analyze-project", { projectPath }),
// Stop a specific feature
stopFeature: (featureId) =>
ipcRenderer.invoke("auto-mode:stop-feature", { featureId }),
// Follow-up on a feature with additional prompt
followUpFeature: (projectPath, featureId, prompt, imagePaths) =>
ipcRenderer.invoke("auto-mode:follow-up-feature", { projectPath, featureId, prompt, imagePaths }),
// Commit changes for a feature
commitFeature: (projectPath, featureId) =>
ipcRenderer.invoke("auto-mode:commit-feature", { projectPath, featureId }),
// Listen for auto mode events
onEvent: (callback) => {
const subscription = (_, data) => callback(data);
ipcRenderer.on("auto-mode:event", subscription);
// Return unsubscribe function
return () => {
ipcRenderer.removeListener("auto-mode:event", subscription);
};
},
},
// Claude CLI Detection API
checkClaudeCli: () => ipcRenderer.invoke("claude:check-cli"),
// Codex CLI Detection API
checkCodexCli: () => ipcRenderer.invoke("codex:check-cli"),
// Model Management APIs
model: {
// Get all available models from all providers
getAvailable: () => ipcRenderer.invoke("model:get-available"),
// Check all provider installation status
checkProviders: () => ipcRenderer.invoke("model:check-providers"),
},
// OpenAI API
testOpenAIConnection: (apiKey) =>
ipcRenderer.invoke("openai:test-connection", { apiKey }),
// Worktree Management APIs
worktree: {
// Revert feature changes by removing the worktree
revertFeature: (projectPath, featureId) =>
ipcRenderer.invoke("worktree:revert-feature", { projectPath, featureId }),
// Merge feature worktree changes back to main branch
mergeFeature: (projectPath, featureId, options) =>
ipcRenderer.invoke("worktree:merge-feature", { projectPath, featureId, options }),
// Get worktree info for a feature
getInfo: (projectPath, featureId) =>
ipcRenderer.invoke("worktree:get-info", { projectPath, featureId }),
// Get worktree status (changed files, commits)
getStatus: (projectPath, featureId) =>
ipcRenderer.invoke("worktree:get-status", { projectPath, featureId }),
// List all feature worktrees
list: (projectPath) =>
ipcRenderer.invoke("worktree:list", { projectPath }),
// Get file diffs for a feature worktree
getDiffs: (projectPath, featureId) =>
ipcRenderer.invoke("worktree:get-diffs", { projectPath, featureId }),
// Get diff for a specific file in a worktree
getFileDiff: (projectPath, featureId, filePath) =>
ipcRenderer.invoke("worktree:get-file-diff", { projectPath, featureId, filePath }),
},
});
// Also expose a flag to detect if we're in Electron
contextBridge.exposeInMainWorld("isElectron", true);