Merge pull request #37 from AutoMaker-Org/refactor/monorepo-restructure

Refactor/monorepo restructure
This commit is contained in:
Web Dev Cody
2025-12-11 23:11:37 -05:00
committed by GitHub
165 changed files with 13322 additions and 14712 deletions

View File

@@ -22,12 +22,12 @@ jobs:
with: with:
node-version: "20" node-version: "20"
cache: "npm" cache: "npm"
cache-dependency-path: app/package-lock.json cache-dependency-path: package-lock.json
- name: Install dependencies - name: Install dependencies
working-directory: ./app # Use npm install instead of npm ci to correctly resolve platform-specific
run: npm ci # optional dependencies (e.g., @tailwindcss/oxide, lightningcss binaries)
run: npm install
- name: Run build:electron - name: Run build:electron
working-directory: ./app
run: npm run build:electron run: npm run build:electron

View File

@@ -3,13 +3,13 @@ name: Build and Release Electron App
on: on:
push: push:
tags: tags:
- 'v*.*.*' # Triggers on version tags like v1.0.0 - "v*.*.*" # Triggers on version tags like v1.0.0
workflow_dispatch: # Allows manual triggering workflow_dispatch: # Allows manual triggering
inputs: inputs:
version: version:
description: 'Version to release (e.g., v1.0.0)' description: "Version to release (e.g., v1.0.0)"
required: true required: true
default: 'v0.1.0' default: "v0.1.0"
jobs: jobs:
build-and-release: build-and-release:
@@ -36,31 +36,29 @@ jobs:
- name: Setup Node.js - name: Setup Node.js
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version: '20' node-version: "20"
cache: 'npm' cache: "npm"
cache-dependency-path: app/package-lock.json cache-dependency-path: package-lock.json
- name: Install dependencies - name: Install dependencies
working-directory: ./app # Use npm install instead of npm ci to correctly resolve platform-specific
run: npm ci # optional dependencies (e.g., @tailwindcss/oxide, lightningcss binaries)
run: npm install
- name: Build Electron App (macOS) - name: Build Electron App (macOS)
if: matrix.os == 'macos-latest' if: matrix.os == 'macos-latest'
working-directory: ./app
env: env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: npm run build:electron -- --mac --x64 --arm64 run: npm run build:electron -- --mac --x64 --arm64
- name: Build Electron App (Windows) - name: Build Electron App (Windows)
if: matrix.os == 'windows-latest' if: matrix.os == 'windows-latest'
working-directory: ./app
env: env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: npm run build:electron -- --win --x64 run: npm run build:electron -- --win --x64
- name: Build Electron App (Linux) - name: Build Electron App (Linux)
if: matrix.os == 'ubuntu-latest' if: matrix.os == 'ubuntu-latest'
working-directory: ./app
env: env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: npm run build:electron -- --linux --x64 run: npm run build:electron -- --linux --x64
@@ -70,12 +68,12 @@ jobs:
with: with:
tag_name: ${{ github.event.inputs.version || github.ref_name }} tag_name: ${{ github.event.inputs.version || github.ref_name }}
files: | files: |
app/dist/*.exe apps/app/dist/*.exe
app/dist/*.dmg apps/app/dist/*.dmg
app/dist/*.AppImage apps/app/dist/*.AppImage
app/dist/*.zip apps/app/dist/*.zip
app/dist/*.deb apps/app/dist/*.deb
app/dist/*.rpm apps/app/dist/*.rpm
draft: false draft: false
prerelease: false prerelease: false
env: env:

9
.gitignore vendored
View File

@@ -1,2 +1,9 @@
#added by trueheads > will remove once supercombo adds multi-os support #added by trueheads > will remove once supercombo adds multi-os support
launch.sh launch.sh
# Dependencies
node_modules/
# Build outputs
dist/
.next/

10
.npmrc Normal file
View File

@@ -0,0 +1,10 @@
# Cross-platform compatibility for Tailwind CSS v4 and lightningcss
# These packages use platform-specific optional dependencies that npm
# automatically resolves based on your OS (macOS, Linux, Windows, WSL)
#
# IMPORTANT: When switching platforms or getting platform mismatch errors:
# 1. Delete node_modules: rm -rf node_modules apps/*/node_modules
# 2. Run: npm install
#
# In CI/CD: Use "npm install" instead of "npm ci" to allow npm to resolve
# the correct platform-specific binaries at install time.

14605
app/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -42,7 +42,10 @@ function createWindow() {
const isDev = !app.isPackaged; const isDev = !app.isPackaged;
if (isDev) { if (isDev) {
mainWindow.loadURL("http://localhost:3007"); mainWindow.loadURL("http://localhost:3007");
// mainWindow.webContents.openDevTools(); // Open DevTools if OPEN_DEVTOOLS environment variable is set
if (process.env.OPEN_DEVTOOLS === "true") {
mainWindow.webContents.openDevTools();
}
} else { } else {
mainWindow.loadFile(path.join(__dirname, "../.next/server/app/index.html")); mainWindow.loadFile(path.join(__dirname, "../.next/server/app/index.html"));
} }
@@ -894,12 +897,9 @@ ipcMain.handle(
async (_, { featureId, status, projectPath, summary }) => { async (_, { featureId, status, projectPath, summary }) => {
try { try {
const featureLoader = require("./services/feature-loader"); const featureLoader = require("./services/feature-loader");
await featureLoader.updateFeatureStatus( await featureLoader.updateFeatureStatus(featureId, status, projectPath, {
featureId, summary,
status, });
projectPath,
{ summary }
);
// Notify renderer if window is available // Notify renderer if window is available
if (mainWindow && !mainWindow.isDestroyed()) { if (mainWindow && !mainWindow.isDestroyed()) {
@@ -931,51 +931,59 @@ let suggestionsExecution = null;
* @param {string} projectPath - The path to the project * @param {string} projectPath - The path to the project
* @param {string} suggestionType - Type of suggestions: "features", "refactoring", "security", "performance" * @param {string} suggestionType - Type of suggestions: "features", "refactoring", "security", "performance"
*/ */
ipcMain.handle("suggestions:generate", async (_, { projectPath, suggestionType = "features" }) => { ipcMain.handle(
try { "suggestions:generate",
// Check if already running async (_, { projectPath, suggestionType = "features" }) => {
if (suggestionsExecution && suggestionsExecution.isActive()) { try {
return { // Check if already running
success: false, if (suggestionsExecution && suggestionsExecution.isActive()) {
error: "Suggestions generation is already running", return {
}; success: false,
} error: "Suggestions generation is already running",
};
// Create execution context
suggestionsExecution = {
abortController: null,
query: null,
isActive: () => suggestionsExecution !== null,
};
const sendToRenderer = (data) => {
if (mainWindow && !mainWindow.isDestroyed()) {
mainWindow.webContents.send("suggestions:event", data);
} }
};
// Start generating suggestions (runs in background) // Create execution context
featureSuggestionsService suggestionsExecution = {
.generateSuggestions(projectPath, sendToRenderer, suggestionsExecution, suggestionType) abortController: null,
.catch((error) => { query: null,
console.error("[IPC] suggestions:generate background error:", error); isActive: () => suggestionsExecution !== null,
sendToRenderer({ };
type: "suggestions_error",
error: error.message, const sendToRenderer = (data) => {
if (mainWindow && !mainWindow.isDestroyed()) {
mainWindow.webContents.send("suggestions:event", data);
}
};
// Start generating suggestions (runs in background)
featureSuggestionsService
.generateSuggestions(
projectPath,
sendToRenderer,
suggestionsExecution,
suggestionType
)
.catch((error) => {
console.error("[IPC] suggestions:generate background error:", error);
sendToRenderer({
type: "suggestions_error",
error: error.message,
});
})
.finally(() => {
suggestionsExecution = null;
}); });
})
.finally(() => {
suggestionsExecution = null;
});
// Return immediately // Return immediately
return { success: true }; return { success: true };
} catch (error) { } catch (error) {
console.error("[IPC] suggestions:generate error:", error); console.error("[IPC] suggestions:generate error:", error);
suggestionsExecution = null; suggestionsExecution = null;
return { success: false, error: error.message }; return { success: false, error: error.message };
}
} }
}); );
/** /**
* Stop the current suggestions generation * Stop the current suggestions generation
@@ -1248,7 +1256,10 @@ ipcMain.handle(
// Check if already running // Check if already running
if (specRegenerationExecution && specRegenerationExecution.isActive()) { if (specRegenerationExecution && specRegenerationExecution.isActive()) {
return { success: false, error: "Spec regeneration is already running" }; return {
success: false,
error: "Spec regeneration is already running",
};
} }
// Create execution context // Create execution context
@@ -1266,7 +1277,11 @@ ipcMain.handle(
// Start generating features (runs in background) // Start generating features (runs in background)
specRegenerationService specRegenerationService
.generateFeaturesOnly(projectPath, sendToRenderer, specRegenerationExecution) .generateFeaturesOnly(
projectPath,
sendToRenderer,
specRegenerationExecution
)
.catch((error) => { .catch((error) => {
console.error( console.error(
"[IPC] spec-regeneration:generate-features background error:", "[IPC] spec-regeneration:generate-features background error:",
@@ -1788,7 +1803,10 @@ ipcMain.handle(
} }
const featureLoader = require("./services/feature-loader"); const featureLoader = require("./services/feature-loader");
const content = await featureLoader.getAgentOutput(projectPath, featureId); const content = await featureLoader.getAgentOutput(
projectPath,
featureId
);
return { success: true, content }; return { success: true, content };
} catch (error) { } catch (error) {
console.error("[IPC] features:getAgentOutput error:", error); console.error("[IPC] features:getAgentOutput error:", error);

View File

@@ -1,5 +1,5 @@
{ {
"name": "automaker", "name": "@automaker/app",
"version": "0.1.0", "version": "0.1.0",
"description": "An autonomous AI development studio that helps you build software faster using AI-powered agents", "description": "An autonomous AI development studio that helps you build software faster using AI-powered agents",
"homepage": "https://github.com/AutoMaker-Org/automaker", "homepage": "https://github.com/AutoMaker-Org/automaker",
@@ -18,6 +18,7 @@
"dev": "next dev -p 3007", "dev": "next dev -p 3007",
"dev:web": "next dev -p 3007", "dev:web": "next dev -p 3007",
"dev:electron": "concurrently \"next dev -p 3007\" \"wait-on http://localhost:3007 && electron .\"", "dev:electron": "concurrently \"next dev -p 3007\" \"wait-on http://localhost:3007 && electron .\"",
"dev:electron:debug": "concurrently \"next dev -p 3007\" \"wait-on http://localhost:3007 && OPEN_DEVTOOLS=true electron .\"",
"build": "next build", "build": "next build",
"build:electron": "next build && electron-builder", "build:electron": "next build && electron-builder",
"start": "next start", "start": "next start",
@@ -47,6 +48,7 @@
"clsx": "^2.1.1", "clsx": "^2.1.1",
"cmdk": "^1.1.1", "cmdk": "^1.1.1",
"dotenv": "^17.2.3", "dotenv": "^17.2.3",
"geist": "^1.5.1",
"lucide-react": "^0.556.0", "lucide-react": "^0.556.0",
"next": "16.0.7", "next": "16.0.7",
"react": "19.2.0", "react": "19.2.0",
@@ -76,6 +78,7 @@
"build": { "build": {
"appId": "com.automaker.app", "appId": "com.automaker.app",
"productName": "Automaker", "productName": "Automaker",
"artifactName": "${productName}-${version}-${arch}.${ext}",
"directories": { "directories": {
"output": "dist" "output": "dist"
}, },
@@ -143,7 +146,8 @@
], ],
"category": "Development", "category": "Development",
"icon": "public/logo_larger.png", "icon": "public/logo_larger.png",
"maintainer": "webdevcody@gmail.com" "maintainer": "webdevcody@gmail.com",
"executableName": "automaker"
}, },
"nsis": { "nsis": {
"oneClick": false, "oneClick": false,

View File

Before

Width:  |  Height:  |  Size: 391 B

After

Width:  |  Height:  |  Size: 391 B

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 142 KiB

After

Width:  |  Height:  |  Size: 142 KiB

View File

Before

Width:  |  Height:  |  Size: 147 KiB

After

Width:  |  Height:  |  Size: 147 KiB

View File

Before

Width:  |  Height:  |  Size: 108 KiB

After

Width:  |  Height:  |  Size: 108 KiB

View File

Before

Width:  |  Height:  |  Size: 262 KiB

After

Width:  |  Height:  |  Size: 262 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 128 B

After

Width:  |  Height:  |  Size: 128 B

View File

Before

Width:  |  Height:  |  Size: 385 B

After

Width:  |  Height:  |  Size: 385 B

View File

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -1,18 +1,8 @@
import type { Metadata } from "next"; import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google"; import { GeistSans } from "geist/font/sans";
import { GeistMono } from "geist/font/mono";
import { Toaster } from "sonner"; import { Toaster } from "sonner";
import "./globals.css"; import "./globals.css";
const geistSans = Geist({
variable: "--font-geist-sans",
subsets: ["latin"],
});
const geistMono = Geist_Mono({
variable: "--font-geist-mono",
subsets: ["latin"],
});
export const metadata: Metadata = { export const metadata: Metadata = {
title: "Automaker - Autonomous AI Development Studio", title: "Automaker - Autonomous AI Development Studio",
description: "Build software autonomously with intelligent orchestration", description: "Build software autonomously with intelligent orchestration",
@@ -26,7 +16,7 @@ export default function RootLayout({
return ( return (
<html lang="en" suppressHydrationWarning> <html lang="en" suppressHydrationWarning>
<body <body
className={`${geistSans.variable} ${geistMono.variable} antialiased`} className={`${GeistSans.variable} ${GeistMono.variable} antialiased`}
> >
{children} {children}
<Toaster richColors position="bottom-right" /> <Toaster richColors position="bottom-right" />

View File

@@ -2322,11 +2322,11 @@ export function BoardView() {
<div className="flex items-center space-x-2"> <div className="flex items-center space-x-2">
<Checkbox <Checkbox
id="skip-tests" id="skip-tests"
checked={newFeature.skipTests} checked={!newFeature.skipTests}
onCheckedChange={(checked) => onCheckedChange={(checked) =>
setNewFeature({ setNewFeature({
...newFeature, ...newFeature,
skipTests: checked === true, skipTests: checked !== true,
}) })
} }
data-testid="skip-tests-checkbox" data-testid="skip-tests-checkbox"
@@ -2336,14 +2336,14 @@ export function BoardView() {
htmlFor="skip-tests" htmlFor="skip-tests"
className="text-sm cursor-pointer" className="text-sm cursor-pointer"
> >
Skip automated testing Enable automated testing
</Label> </Label>
<FlaskConical className="w-3.5 h-3.5 text-muted-foreground" /> <FlaskConical className="w-3.5 h-3.5 text-muted-foreground" />
</div> </div>
</div> </div>
<p className="text-xs text-muted-foreground"> <p className="text-xs text-muted-foreground">
When enabled, this feature will require manual verification When enabled, this feature will use automated TDD. When
instead of automated TDD. disabled, it will require manual verification.
</p> </p>
{/* Verification Steps - Only shown when skipTests is enabled */} {/* Verification Steps - Only shown when skipTests is enabled */}
@@ -2742,11 +2742,11 @@ export function BoardView() {
<div className="flex items-center space-x-2"> <div className="flex items-center space-x-2">
<Checkbox <Checkbox
id="edit-skip-tests" id="edit-skip-tests"
checked={editingFeature.skipTests ?? false} checked={!(editingFeature.skipTests ?? false)}
onCheckedChange={(checked) => onCheckedChange={(checked) =>
setEditingFeature({ setEditingFeature({
...editingFeature, ...editingFeature,
skipTests: checked === true, skipTests: checked !== true,
}) })
} }
data-testid="edit-skip-tests-checkbox" data-testid="edit-skip-tests-checkbox"
@@ -2756,14 +2756,14 @@ export function BoardView() {
htmlFor="edit-skip-tests" htmlFor="edit-skip-tests"
className="text-sm cursor-pointer" className="text-sm cursor-pointer"
> >
Skip automated testing Enable automated testing
</Label> </Label>
<FlaskConical className="w-3.5 h-3.5 text-muted-foreground" /> <FlaskConical className="w-3.5 h-3.5 text-muted-foreground" />
</div> </div>
</div> </div>
<p className="text-xs text-muted-foreground"> <p className="text-xs text-muted-foreground">
When enabled, this feature will require manual verification When enabled, this feature will use automated TDD. When
instead of automated TDD. disabled, it will require manual verification.
</p> </p>
{/* Verification Steps - Only shown when skipTests is enabled */} {/* Verification Steps - Only shown when skipTests is enabled */}

Some files were not shown because too many files have changed in this diff Show More