Files
automaker/app/electron/preload.js
Cody Seibert 15981c8e1b feat: restructure feature management and update project files
- Introduced a new `package-lock.json` to manage dependencies.
- Removed obsolete `.automaker/feature_list.json` and replaced it with a new structure under `.automaker/features/{id}/feature.json` for better organization.
- Updated various components to utilize the new features API for managing features, including creation, updates, and deletions.
- Enhanced the UI to reflect changes in feature management, including updates to the sidebar and board view.
- Improved documentation and comments throughout the codebase to clarify the new feature management process.
2025-12-10 19:11:36 -05:00

389 lines
12 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, projectPath) =>
ipcRenderer.invoke("app:saveImageToTemp", {
data,
filename,
mimeType,
projectPath,
}),
// 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);
};
},
},
// Features API
features: {
// Get all features for a project
getAll: (projectPath) =>
ipcRenderer.invoke("features:getAll", { projectPath }),
// Get a single feature by ID
get: (projectPath, featureId) =>
ipcRenderer.invoke("features:get", { projectPath, featureId }),
// Create a new feature
create: (projectPath, feature) =>
ipcRenderer.invoke("features:create", { projectPath, feature }),
// Update a feature (partial updates supported)
update: (projectPath, featureId, updates) =>
ipcRenderer.invoke("features:update", {
projectPath,
featureId,
updates,
}),
// Delete a feature and its folder
delete: (projectPath, featureId) =>
ipcRenderer.invoke("features:delete", { projectPath, featureId }),
// Get agent output for a feature
getAgentOutput: (projectPath, featureId) =>
ipcRenderer.invoke("features:getAgentOutput", { projectPath, featureId }),
},
});
// Also expose a flag to detect if we're in Electron
contextBridge.exposeInMainWorld("isElectron", true);