mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-01-31 06:42:03 +00:00
- Added a new SetupView component to guide users through the installation and authentication of Claude and Codex CLIs. - Integrated IPC handlers for checking CLI status, installing, and authenticating both CLIs. - Enhanced the app store to manage setup state, including first run detection and progress tracking. - Updated the main application view to redirect to the setup wizard on first run. - Improved user experience by providing clear instructions and feedback during the setup process. These changes streamline the initial configuration of CLI tools, ensuring users can easily set up their development environment.
312 lines
11 KiB
JavaScript
312 lines
11 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, useWorktrees) =>
|
|
ipcRenderer.invoke("auto-mode:run-feature", { projectPath, featureId, useWorktrees }),
|
|
|
|
// 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 }),
|
|
},
|
|
|
|
// Git Operations APIs (for non-worktree operations)
|
|
git: {
|
|
// Get file diffs for the main project
|
|
getDiffs: (projectPath) =>
|
|
ipcRenderer.invoke("git:get-diffs", { projectPath }),
|
|
|
|
// Get diff for a specific file in the main project
|
|
getFileDiff: (projectPath, filePath) =>
|
|
ipcRenderer.invoke("git:get-file-diff", { projectPath, filePath }),
|
|
},
|
|
|
|
// Feature Suggestions API
|
|
suggestions: {
|
|
// Generate feature suggestions
|
|
generate: (projectPath) =>
|
|
ipcRenderer.invoke("suggestions:generate", { projectPath }),
|
|
|
|
// Stop generating suggestions
|
|
stop: () => ipcRenderer.invoke("suggestions:stop"),
|
|
|
|
// Get suggestions status
|
|
status: () => ipcRenderer.invoke("suggestions:status"),
|
|
|
|
// Listen for suggestions events
|
|
onEvent: (callback) => {
|
|
const subscription = (_, data) => callback(data);
|
|
ipcRenderer.on("suggestions:event", subscription);
|
|
|
|
// Return unsubscribe function
|
|
return () => {
|
|
ipcRenderer.removeListener("suggestions:event", subscription);
|
|
};
|
|
},
|
|
},
|
|
|
|
// Spec Regeneration API
|
|
specRegeneration: {
|
|
// Create initial app spec for a new project
|
|
create: (projectPath, projectOverview, generateFeatures = true) =>
|
|
ipcRenderer.invoke("spec-regeneration:create", { projectPath, projectOverview, generateFeatures }),
|
|
|
|
// Regenerate the app spec
|
|
generate: (projectPath, projectDefinition) =>
|
|
ipcRenderer.invoke("spec-regeneration:generate", { projectPath, projectDefinition }),
|
|
|
|
// Stop regenerating spec
|
|
stop: () => ipcRenderer.invoke("spec-regeneration:stop"),
|
|
|
|
// Get regeneration status
|
|
status: () => ipcRenderer.invoke("spec-regeneration:status"),
|
|
|
|
// Listen for regeneration events
|
|
onEvent: (callback) => {
|
|
const subscription = (_, data) => callback(data);
|
|
ipcRenderer.on("spec-regeneration:event", subscription);
|
|
|
|
// Return unsubscribe function
|
|
return () => {
|
|
ipcRenderer.removeListener("spec-regeneration:event", subscription);
|
|
};
|
|
},
|
|
},
|
|
|
|
// Setup & CLI Management API
|
|
setup: {
|
|
// Get comprehensive Claude CLI status
|
|
getClaudeStatus: () => ipcRenderer.invoke("setup:claude-status"),
|
|
|
|
// Get comprehensive Codex CLI status
|
|
getCodexStatus: () => ipcRenderer.invoke("setup:codex-status"),
|
|
|
|
// Install Claude CLI
|
|
installClaude: () => ipcRenderer.invoke("setup:install-claude"),
|
|
|
|
// Install Codex CLI
|
|
installCodex: () => ipcRenderer.invoke("setup:install-codex"),
|
|
|
|
// Authenticate Claude CLI
|
|
authClaude: () => ipcRenderer.invoke("setup:auth-claude"),
|
|
|
|
// Authenticate Codex CLI with optional API key
|
|
authCodex: (apiKey) => ipcRenderer.invoke("setup:auth-codex", { apiKey }),
|
|
|
|
// Store API key securely
|
|
storeApiKey: (provider, apiKey) =>
|
|
ipcRenderer.invoke("setup:store-api-key", { provider, apiKey }),
|
|
|
|
// Get stored API keys status
|
|
getApiKeys: () => ipcRenderer.invoke("setup:get-api-keys"),
|
|
|
|
// Configure Codex MCP server for a project
|
|
configureCodexMcp: (projectPath) =>
|
|
ipcRenderer.invoke("setup:configure-codex-mcp", { projectPath }),
|
|
|
|
// Get platform information
|
|
getPlatform: () => ipcRenderer.invoke("setup:get-platform"),
|
|
|
|
// Listen for installation progress
|
|
onInstallProgress: (callback) => {
|
|
const subscription = (_, data) => callback(data);
|
|
ipcRenderer.on("setup:install-progress", subscription);
|
|
return () => {
|
|
ipcRenderer.removeListener("setup:install-progress", subscription);
|
|
};
|
|
},
|
|
|
|
// Listen for auth progress
|
|
onAuthProgress: (callback) => {
|
|
const subscription = (_, data) => callback(data);
|
|
ipcRenderer.on("setup:auth-progress", subscription);
|
|
return () => {
|
|
ipcRenderer.removeListener("setup:auth-progress", subscription);
|
|
};
|
|
},
|
|
},
|
|
});
|
|
|
|
// Also expose a flag to detect if we're in Electron
|
|
contextBridge.exposeInMainWorld("isElectron", true);
|