session config

This commit is contained in:
Amrit Subramanian 2025-10-02 20:20:05 -04:00
parent 66e0c96b75
commit f61aca9d09
6 changed files with 494 additions and 11 deletions

View file

@ -45,6 +45,41 @@
</div>
</div>
<!-- Session Configuration Modal -->
<div id="config-modal" class="modal-overlay hidden">
<div class="modal">
<h2 class="modal-title">New Session Configuration</h2>
<div class="form-group">
<label class="form-label">Project Directory</label>
<div class="directory-input-group">
<input type="text" id="project-dir" class="form-input" readonly placeholder="Select a directory..." />
<button id="browse-dir" class="btn-icon">Browse</button>
</div>
</div>
<div class="form-group">
<label class="form-label">Parent Branch</label>
<select id="parent-branch" class="form-select">
<option value="">Loading branches...</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Coding Agent</label>
<select id="coding-agent" class="form-select">
<option value="claude">Claude</option>
<option value="codex">Codex</option>
</select>
</div>
<div class="btn-group">
<button id="cancel-session" class="btn-secondary">Cancel</button>
<button id="create-session" class="btn-primary">Create Session</button>
</div>
</div>
</div>
<script>
require('./dist/renderer.js');
</script>

42
main.ts
View file

@ -1,12 +1,46 @@
import { app, BrowserWindow, ipcMain } from "electron";
import { app, BrowserWindow, ipcMain, dialog } from "electron";
import * as pty from "node-pty";
import * as os from "os";
import { simpleGit } from "simple-git";
import Store from "electron-store";
interface SessionConfig {
projectDir: string;
parentBranch: string;
codingAgent: string;
}
let mainWindow: BrowserWindow;
const sessions = new Map<string, pty.IPty>();
const store = new Store();
// Open directory picker
ipcMain.handle("select-directory", async () => {
const result = await dialog.showOpenDialog(mainWindow, {
properties: ["openDirectory"],
});
if (result.canceled || result.filePaths.length === 0) {
return null;
}
return result.filePaths[0];
});
// Get git branches from directory
ipcMain.handle("get-branches", async (_event, dirPath: string) => {
try {
const git = simpleGit(dirPath);
const branchSummary = await git.branch();
return branchSummary.all;
} catch (error) {
console.error("Error getting branches:", error);
return [];
}
});
// Create new session
ipcMain.on("create-session", (event) => {
ipcMain.on("create-session", (event, config: SessionConfig) => {
const sessionId = `session-${Date.now()}`;
const shell = os.platform() === "darwin" ? "zsh" : "bash";
@ -14,7 +48,7 @@ ipcMain.on("create-session", (event) => {
name: "xterm-color",
cols: 80,
rows: 30,
cwd: process.env.HOME,
cwd: config.projectDir || process.env.HOME,
env: process.env,
});
@ -24,7 +58,7 @@ ipcMain.on("create-session", (event) => {
mainWindow.webContents.send("session-output", sessionId, data);
});
event.reply("session-created", sessionId);
event.reply("session-created", sessionId, config);
});
// Handle session input

289
package-lock.json generated
View file

@ -9,7 +9,9 @@
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"electron-store": "^11.0.0",
"node-pty": "^1.0.0",
"simple-git": "^3.28.0",
"xterm": "^5.3.0",
"xterm-addon-fit": "^0.8.0"
},
@ -695,6 +697,21 @@
"@jridgewell/sourcemap-codec": "^1.4.10"
}
},
"node_modules/@kwsites/file-exists": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz",
"integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==",
"license": "MIT",
"dependencies": {
"debug": "^4.1.1"
}
},
"node_modules/@kwsites/promise-deferred": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz",
"integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==",
"license": "MIT"
},
"node_modules/@malept/cross-spawn-promise": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-2.0.0.tgz",
@ -1084,6 +1101,39 @@
"node": ">=8"
}
},
"node_modules/ajv": {
"version": "8.17.1",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
"license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.3",
"fast-uri": "^3.0.1",
"json-schema-traverse": "^1.0.0",
"require-from-string": "^2.0.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/ajv-formats": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz",
"integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==",
"license": "MIT",
"dependencies": {
"ajv": "^8.0.0"
},
"peerDependencies": {
"ajv": "^8.0.0"
},
"peerDependenciesMeta": {
"ajv": {
"optional": true
}
}
},
"node_modules/ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
@ -1173,6 +1223,15 @@
"dev": true,
"license": "MIT"
},
"node_modules/atomically": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/atomically/-/atomically-2.0.3.tgz",
"integrity": "sha512-kU6FmrwZ3Lx7/7y3hPS5QnbJfaohcIul5fGqf7ok+4KklIEk9tJ0C2IQPdacSbVUWv6zVHXEBWoWd6NrVMT7Cw==",
"dependencies": {
"stubborn-fs": "^1.2.5",
"when-exit": "^2.1.1"
}
},
"node_modules/autoprefixer": {
"version": "10.4.21",
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz",
@ -1696,6 +1755,53 @@
"dev": true,
"license": "MIT"
},
"node_modules/conf": {
"version": "15.0.0",
"resolved": "https://registry.npmjs.org/conf/-/conf-15.0.0.tgz",
"integrity": "sha512-w9BzJHS5swhxUq3+nF5hbI0XbfCNH5nfP/IL4HpkmdLtejSPen20hvRkcnk8Xht7YyLoHjvxDm99bqsa1l9qlw==",
"license": "MIT",
"dependencies": {
"ajv": "^8.17.1",
"ajv-formats": "^3.0.1",
"atomically": "^2.0.3",
"debounce-fn": "^6.0.0",
"dot-prop": "^10.0.0",
"env-paths": "^3.0.0",
"json-schema-typed": "^8.0.1",
"semver": "^7.7.2",
"uint8array-extras": "^1.5.0"
},
"engines": {
"node": ">=20"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/conf/node_modules/env-paths": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-3.0.0.tgz",
"integrity": "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==",
"license": "MIT",
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/conf/node_modules/semver": {
"version": "7.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/console-control-strings": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
@ -1738,11 +1844,25 @@
"node": ">=4"
}
},
"node_modules/debounce-fn": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/debounce-fn/-/debounce-fn-6.0.0.tgz",
"integrity": "sha512-rBMW+F2TXryBwB54Q0d8drNEI+TfoS9JpNTAoVpukbWEhjXQq4rySFYLaqXMFXwdv61Zb2OHtj5bviSoimqxRQ==",
"license": "MIT",
"dependencies": {
"mimic-function": "^5.0.0"
},
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/debug": {
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
"dev": true,
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
@ -1895,6 +2015,36 @@
"dev": true,
"license": "MIT"
},
"node_modules/dot-prop": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-10.0.0.tgz",
"integrity": "sha512-s7RhKKTxc+GiZkfewpLsuWpPeCPe0patP9G/qRJ2VN/BWA+Ydq65K2Pfse234zjGszTVJCzPLze54vD8eyE8NQ==",
"license": "MIT",
"dependencies": {
"type-fest": "^5.0.0"
},
"engines": {
"node": ">=20"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/dot-prop/node_modules/type-fest": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.0.1.tgz",
"integrity": "sha512-9MpwAI52m8H6ssA542UxSLnSiSD2dsC3/L85g6hVubLSXd82wdI80eZwTWhdOfN67NlA+D+oipAs1MlcTcu3KA==",
"license": "(MIT OR CC0-1.0)",
"dependencies": {
"tagged-tag": "^1.0.0"
},
"engines": {
"node": ">=20"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/eastasianwidth": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
@ -2002,6 +2152,37 @@
"node": ">= 10.0.0"
}
},
"node_modules/electron-store": {
"version": "11.0.0",
"resolved": "https://registry.npmjs.org/electron-store/-/electron-store-11.0.0.tgz",
"integrity": "sha512-msCXEmzIGdnIq/u3od5mh/Hk5mZAGKa+3gGGTQcqPPkHcD/otlLyIZuRd1WAOhhg0gKo17BK5Avsl7OHkxir7w==",
"license": "MIT",
"dependencies": {
"conf": "^15.0.0",
"type-fest": "^5.0.1"
},
"engines": {
"node": ">=20"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/electron-store/node_modules/type-fest": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.0.1.tgz",
"integrity": "sha512-9MpwAI52m8H6ssA542UxSLnSiSD2dsC3/L85g6hVubLSXd82wdI80eZwTWhdOfN67NlA+D+oipAs1MlcTcu3KA==",
"license": "(MIT OR CC0-1.0)",
"dependencies": {
"tagged-tag": "^1.0.0"
},
"engines": {
"node": ">=20"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/electron-to-chromium": {
"version": "1.5.228",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.228.tgz",
@ -2153,6 +2334,12 @@
"@types/yauzl": "^2.9.1"
}
},
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"license": "MIT"
},
"node_modules/fast-glob": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
@ -2183,6 +2370,22 @@
"node": ">= 6"
}
},
"node_modules/fast-uri": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz",
"integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/fastify"
},
{
"type": "opencollective",
"url": "https://opencollective.com/fastify"
}
],
"license": "BSD-3-Clause"
},
"node_modules/fastq": {
"version": "1.19.1",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
@ -2855,6 +3058,18 @@
"dev": true,
"license": "MIT"
},
"node_modules/json-schema-traverse": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
"license": "MIT"
},
"node_modules/json-schema-typed": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.1.tgz",
"integrity": "sha512-XQmWYj2Sm4kn4WeTYvmpKEbyPsL7nBsb647c7pMe6l02/yx2+Jfc4dT6UZkEXnIUb5LhD55r2HPsJ1milQ4rDg==",
"license": "BSD-2-Clause"
},
"node_modules/json-stringify-safe": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
@ -3055,6 +3270,18 @@
"node": ">=6"
}
},
"node_modules/mimic-function": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz",
"integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==",
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/mimic-response": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
@ -3192,7 +3419,6 @@
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true,
"license": "MIT"
},
"node_modules/mz": {
@ -3977,6 +4203,15 @@
"node": ">=0.10.0"
}
},
"node_modules/require-from-string": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/resolve": {
"version": "1.22.10",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
@ -4214,6 +4449,21 @@
"dev": true,
"license": "ISC"
},
"node_modules/simple-git": {
"version": "3.28.0",
"resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.28.0.tgz",
"integrity": "sha512-Rs/vQRwsn1ILH1oBUy8NucJlXmnnLeLCfcvbSehkPzbv3wwoFWIdtfd6Ndo6ZPhlPsCZ60CPI4rxurnwAa+a2w==",
"license": "MIT",
"dependencies": {
"@kwsites/file-exists": "^1.1.1",
"@kwsites/promise-deferred": "^1.1.1",
"debug": "^4.4.0"
},
"funding": {
"type": "github",
"url": "https://github.com/steveukx/git-js?sponsor=1"
}
},
"node_modules/smart-buffer": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
@ -4354,6 +4604,11 @@
"node": ">=8"
}
},
"node_modules/stubborn-fs": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/stubborn-fs/-/stubborn-fs-1.2.5.tgz",
"integrity": "sha512-H2N9c26eXjzL/S/K+i/RHHcFanE74dptvvjM8iwzwbVcWY/zjBbgRqF3K0DY4+OD+uTTASTBvDoxPDaPN02D7g=="
},
"node_modules/sucrase": {
"version": "3.35.0",
"resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",
@ -4473,6 +4728,18 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/tagged-tag": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/tagged-tag/-/tagged-tag-1.0.0.tgz",
"integrity": "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==",
"license": "MIT",
"engines": {
"node": ">=20"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/tailwindcss": {
"version": "3.4.18",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.18.tgz",
@ -4678,6 +4945,18 @@
"node": ">=14.17"
}
},
"node_modules/uint8array-extras": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.5.0.tgz",
"integrity": "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==",
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/undici-types": {
"version": "7.13.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.13.0.tgz",
@ -4776,6 +5055,12 @@
"defaults": "^1.0.3"
}
},
"node_modules/when-exit": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/when-exit/-/when-exit-2.1.4.tgz",
"integrity": "sha512-4rnvd3A1t16PWzrBUcSDZqcAmsUIy4minDXT/CZ8F2mVDgd65i4Aalimgz1aQkRGU0iH5eT5+6Rx2TK8o443Pg==",
"license": "MIT"
},
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",

View file

@ -25,7 +25,9 @@
"typescript": "^5.9.3"
},
"dependencies": {
"electron-store": "^11.0.0",
"node-pty": "^1.0.0",
"simple-git": "^3.28.0",
"xterm": "^5.3.0",
"xterm-addon-fit": "^0.8.0"
}

View file

@ -2,18 +2,25 @@ import { ipcRenderer } from "electron";
import { Terminal } from "xterm";
import { FitAddon } from "xterm-addon-fit";
interface SessionConfig {
projectDir: string;
parentBranch: string;
codingAgent: string;
}
interface Session {
id: string;
terminal: Terminal;
fitAddon: FitAddon;
element: HTMLDivElement;
name: string;
config: SessionConfig;
}
const sessions = new Map<string, Session>();
let activeSessionId: string | null = null;
function createSession(sessionId: string, name: string) {
function createSession(sessionId: string, name: string, config: SessionConfig) {
const term = new Terminal({
cursorBlink: true,
fontSize: 14,
@ -49,6 +56,7 @@ function createSession(sessionId: string, name: string) {
fitAddon,
element: sessionElement,
name,
config,
};
sessions.set(sessionId, session);
@ -189,12 +197,78 @@ ipcRenderer.on("session-output", (_event, sessionId: string, data: string) => {
});
// Handle session created
ipcRenderer.on("session-created", (_event, sessionId: string) => {
ipcRenderer.on("session-created", (_event, sessionId: string, config: SessionConfig) => {
const name = `Session ${sessions.size + 1}`;
createSession(sessionId, name);
createSession(sessionId, name, config);
});
// New session button
// Modal handling
const modal = document.getElementById("config-modal");
const projectDirInput = document.getElementById("project-dir") as HTMLInputElement;
const parentBranchSelect = document.getElementById("parent-branch") as HTMLSelectElement;
const codingAgentSelect = document.getElementById("coding-agent") as HTMLSelectElement;
const browseDirBtn = document.getElementById("browse-dir");
const cancelBtn = document.getElementById("cancel-session");
const createBtn = document.getElementById("create-session");
let selectedDirectory = "";
// New session button - opens modal
document.getElementById("new-session")?.addEventListener("click", () => {
ipcRenderer.send("create-session");
modal?.classList.remove("hidden");
});
// Browse directory
browseDirBtn?.addEventListener("click", async () => {
const dir = await ipcRenderer.invoke("select-directory");
if (dir) {
selectedDirectory = dir;
projectDirInput.value = dir;
// Load git branches
const branches = await ipcRenderer.invoke("get-branches", dir);
parentBranchSelect.innerHTML = "";
if (branches.length === 0) {
parentBranchSelect.innerHTML = '<option value="">No git repository found</option>';
} else {
branches.forEach((branch: string) => {
const option = document.createElement("option");
option.value = branch;
option.textContent = branch;
parentBranchSelect.appendChild(option);
});
}
}
});
// Cancel button
cancelBtn?.addEventListener("click", () => {
modal?.classList.add("hidden");
projectDirInput.value = "";
selectedDirectory = "";
parentBranchSelect.innerHTML = '<option value="">Loading branches...</option>';
});
// Create session button
createBtn?.addEventListener("click", () => {
if (!selectedDirectory) {
alert("Please select a project directory");
return;
}
const config: SessionConfig = {
projectDir: selectedDirectory,
parentBranch: parentBranchSelect.value,
codingAgent: codingAgentSelect.value,
};
ipcRenderer.send("create-session", config);
modal?.classList.add("hidden");
// Reset form
projectDirInput.value = "";
selectedDirectory = "";
parentBranchSelect.innerHTML = '<option value="">Loading branches...</option>';
codingAgentSelect.value = "claude";
});

View file

@ -85,4 +85,57 @@
.session-wrapper.active {
@apply block;
}
/* Modal */
.modal-overlay {
@apply fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50;
}
.modal-overlay.hidden {
display: none;
}
.modal {
@apply bg-gray-800 rounded-lg shadow-xl w-full max-w-md p-6;
}
.modal-title {
@apply text-xl font-semibold text-white mb-4;
}
.form-group {
@apply mb-4;
}
.form-label {
@apply block text-sm font-medium text-gray-300 mb-2;
}
.form-input {
@apply w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-white focus:outline-none focus:border-blue-500;
}
.form-select {
@apply w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-white focus:outline-none focus:border-blue-500;
}
.btn-secondary {
@apply bg-gray-600 hover:bg-gray-700 text-white px-4 py-2 rounded text-sm font-medium transition;
}
.btn-group {
@apply flex justify-end space-x-3 mt-6;
}
.directory-input-group {
@apply flex space-x-2;
}
.directory-input-group .form-input {
@apply flex-1;
}
.btn-icon {
@apply bg-gray-600 hover:bg-gray-700 text-white px-3 py-2 rounded text-sm font-medium transition;
}
}