diff --git a/apps/app/electron/main.js b/apps/app/electron/main.js
index 9ae31c32..0fd95d97 100644
--- a/apps/app/electron/main.js
+++ b/apps/app/electron/main.js
@@ -7,6 +7,7 @@
const path = require("path");
const { spawn } = require("child_process");
+const fs = require("fs");
// Load environment variables from .env file
require("dotenv").config({ path: path.join(__dirname, "../.env") });
@@ -30,10 +31,39 @@ function getIconPath() {
async function startServer() {
const isDev = !app.isPackaged;
- // Server entry point
- const serverPath = isDev
- ? path.join(__dirname, "../../server/dist/index.js")
- : path.join(process.resourcesPath, "server", "index.js");
+ // Server entry point - use tsx in dev, compiled version in production
+ let command, args, serverPath;
+ if (isDev) {
+ // In development, use tsx to run TypeScript directly
+ // Use the node executable that's running Electron
+ command = process.execPath; // This is the path to node.exe
+ serverPath = path.join(__dirname, "../../server/src/index.ts");
+
+ // Find tsx CLI - check server node_modules first, then root
+ const serverNodeModules = path.join(__dirname, "../../server/node_modules/tsx");
+ const rootNodeModules = path.join(__dirname, "../../../node_modules/tsx");
+
+ let tsxCliPath;
+ if (fs.existsSync(path.join(serverNodeModules, "dist/cli.mjs"))) {
+ tsxCliPath = path.join(serverNodeModules, "dist/cli.mjs");
+ } else if (fs.existsSync(path.join(rootNodeModules, "dist/cli.mjs"))) {
+ tsxCliPath = path.join(rootNodeModules, "dist/cli.mjs");
+ } else {
+ // Last resort: try require.resolve
+ try {
+ tsxCliPath = require.resolve("tsx/cli.mjs", { paths: [path.join(__dirname, "../../server")] });
+ } catch {
+ throw new Error("Could not find tsx. Please run 'npm install' in the server directory.");
+ }
+ }
+
+ args = [tsxCliPath, "watch", serverPath];
+ } else {
+ // In production, use compiled JavaScript
+ command = "node";
+ serverPath = path.join(process.resourcesPath, "server", "index.js");
+ args = [serverPath];
+ }
// Set environment variables for server
const env = {
@@ -44,7 +74,7 @@ async function startServer() {
console.log("[Electron] Starting backend server...");
- serverProcess = spawn("node", [serverPath], {
+ serverProcess = spawn(command, args, {
env,
stdio: ["ignore", "pipe", "pipe"],
});
diff --git a/apps/app/package.json b/apps/app/package.json
index 9c973c0e..98a8b0b4 100644
--- a/apps/app/package.json
+++ b/apps/app/package.json
@@ -42,6 +42,9 @@
"@radix-ui/react-tabs": "^1.1.13",
"@radix-ui/react-tooltip": "^1.2.8",
"@tanstack/react-query": "^5.90.12",
+ "@xterm/addon-fit": "^0.10.0",
+ "@xterm/addon-webgl": "^0.18.0",
+ "@xterm/xterm": "^5.5.0",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"cmdk": "^1.1.1",
@@ -52,6 +55,7 @@
"react": "19.2.0",
"react-dom": "19.2.0",
"react-markdown": "^10.1.0",
+ "react-resizable-panels": "^3.0.6",
"sonner": "^2.0.7",
"tailwind-merge": "^3.4.0",
"zustand": "^5.0.9"
diff --git a/apps/app/src/app/globals.css b/apps/app/src/app/globals.css
index 1e522a2b..af1f2f93 100644
--- a/apps/app/src/app/globals.css
+++ b/apps/app/src/app/globals.css
@@ -1177,12 +1177,12 @@
}
/* Custom scrollbar for dark themes */
-:is(.dark, .retro, .dracula, .nord, .monokai, .tokyonight, .solarized, .gruvbox, .catppuccin, .onedark, .synthwave) ::-webkit-scrollbar {
+:is(.dark, .retro, .dracula, .nord, .monokai, .tokyonight, .solarized, .gruvbox, .catppuccin, .onedark, .synthwave, .red) ::-webkit-scrollbar {
width: 8px;
height: 8px;
}
-:is(.dark, .retro, .dracula, .nord, .monokai, .tokyonight, .solarized, .gruvbox, .catppuccin, .onedark, .synthwave) ::-webkit-scrollbar-track {
+:is(.dark, .retro, .dracula, .nord, .monokai, .tokyonight, .solarized, .gruvbox, .catppuccin, .onedark, .synthwave, .red) ::-webkit-scrollbar-track {
background: var(--muted);
}
@@ -1204,6 +1204,20 @@
background: var(--background);
}
+/* Red theme scrollbar */
+.red ::-webkit-scrollbar-thumb {
+ background: oklch(0.35 0.15 25);
+ border-radius: 4px;
+}
+
+.red ::-webkit-scrollbar-thumb:hover {
+ background: oklch(0.45 0.18 25);
+}
+
+.red ::-webkit-scrollbar-track {
+ background: oklch(0.15 0.05 25);
+}
+
/* Always visible scrollbar for file diffs and code blocks */
.scrollbar-visible {
overflow-y: auto !important;
diff --git a/apps/app/src/app/page.tsx b/apps/app/src/app/page.tsx
index 0397f513..06dfd503 100644
--- a/apps/app/src/app/page.tsx
+++ b/apps/app/src/app/page.tsx
@@ -12,6 +12,8 @@ import { ContextView } from "@/components/views/context-view";
import { ProfilesView } from "@/components/views/profiles-view";
import { SetupView } from "@/components/views/setup-view";
import { RunningAgentsView } from "@/components/views/running-agents-view";
+import { TerminalView } from "@/components/views/terminal-view";
+import { WikiView } from "@/components/views/wiki-view";
import { useAppStore } from "@/store/app-store";
import { useSetupStore } from "@/store/setup-store";
import { getElectronAPI, isElectron } from "@/lib/electron";
@@ -206,6 +208,10 @@ function HomeContent() {
return ;
case "running-agents":
return ;
+ case "terminal":
+ return ;
+ case "wiki":
+ return ;
default:
return ;
}
diff --git a/apps/app/src/components/layout/sidebar.tsx b/apps/app/src/components/layout/sidebar.tsx
index f1efa237..dce4a435 100644
--- a/apps/app/src/components/layout/sidebar.tsx
+++ b/apps/app/src/components/layout/sidebar.tsx
@@ -32,6 +32,9 @@ import {
Bug,
Activity,
Recycle,
+ Sparkles,
+ Loader2,
+ Terminal,
} from "lucide-react";
import {
DropdownMenu,
@@ -72,7 +75,6 @@ import {
hasAutomakerDir,
} from "@/lib/project-init";
import { toast } from "sonner";
-import { Sparkles, Loader2 } from "lucide-react";
import { themeOptions } from "@/config/theme-options";
import { Checkbox } from "@/components/ui/checkbox";
import type { SpecRegenerationEvent } from "@/types/electron";
@@ -609,6 +611,12 @@ export function Sidebar() {
icon: UserCircle,
shortcut: shortcuts.profiles,
},
+ {
+ id: "terminal",
+ label: "Terminal",
+ icon: Terminal,
+ shortcut: shortcuts.terminal,
+ },
],
},
];
@@ -1239,6 +1247,46 @@ export function Sidebar() {
{/* Course Promo Badge */}
+ {/* Wiki Link */}
+
+
+
{/* Running Agents Link */}