Interrupted runs now return to the queue instead of failing - an app shutdown is not a model error and must not spend the task's bounded retry budget. Startup work moves behind the single-instance lock so a losing second instance can never run recovery against the live instance's database. Background provider requests that died before receiving an external response id now fail at boot (the background worker can only resume accepted ones). Agent updates resolve the department through the same canonical lookup as hires, replacing the free-text write and its invented "General" default.
58 lines
2.0 KiB
TypeScript
58 lines
2.0 KiB
TypeScript
import { app } from "electron";
|
|
import { dirname, join } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import { DatabaseConnection } from "./database/connection";
|
|
import { createMainWindow } from "./app/create-window";
|
|
import { registerIpcHandlers } from "./app/ipc-handlers";
|
|
import { startProviderBackgroundWorker } from "./app/provider-background-worker";
|
|
import { recoverInterruptedWork } from "./app/startup-recovery";
|
|
import { startTaskQueueWorker } from "./app/task-queue-worker";
|
|
|
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
|
|
// A losing second instance must never touch the database: quit is
|
|
// asynchronous, so all startup work stays behind the lock check.
|
|
if (!app.requestSingleInstanceLock()) {
|
|
app.quit();
|
|
} else {
|
|
app.whenReady().then(() => {
|
|
const profileDir = process.env.AGENTCOMPANY_NEW_PROFILE_DIR ?? join(app.getPath("userData"), "profile");
|
|
const connection = new DatabaseConnection(join(profileDir, "agentcompany.db"));
|
|
connection.transaction(() => recoverInterruptedWork(connection.db));
|
|
const win = createMainWindow({
|
|
preloadPath: join(__dirname, "../preload/index.js"),
|
|
rendererDist: join(__dirname, "../renderer"),
|
|
devServerUrl: process.env.ELECTRON_RENDERER_URL,
|
|
});
|
|
|
|
registerIpcHandlers({
|
|
connection,
|
|
mainWindow: win,
|
|
artifactRoot: join(profileDir, "artifacts"),
|
|
});
|
|
const stopProviderBackgroundWorker = startProviderBackgroundWorker({
|
|
db: connection.db,
|
|
mainWindow: win,
|
|
});
|
|
const autonomousExecution = process.env.AGENTCOMPANY_NEW_AUTORUN !== "0";
|
|
const stopTaskQueueWorker = autonomousExecution
|
|
? startTaskQueueWorker({ connection, mainWindow: win })
|
|
: () => {};
|
|
|
|
app.on("second-instance", () => {
|
|
if (win.isMinimized()) win.restore();
|
|
win.focus();
|
|
});
|
|
|
|
app.on("before-quit", () => {
|
|
stopProviderBackgroundWorker();
|
|
stopTaskQueueWorker();
|
|
connection.close();
|
|
});
|
|
});
|
|
|
|
app.on("window-all-closed", () => {
|
|
if (process.platform !== "darwin") app.quit();
|
|
});
|
|
}
|