feat(main): add Electron entry + Inbox window shell

Task 2 of the slice plan. Creates the minimal Electron main
process: app entry that opens an Inbox BrowserWindow on
whenReady, an inboxWindow module that handles show/hide/close-
to-tray semantics, an HTML placeholder renderer ("Inkling Inbox
(renderer pending)"), and the minimum @shared/types augmentation
for app.isQuitting (Task 3 expands this file).

Plan tsconfig template adjustment: TypeScript 6 deprecates
baseUrl. Dropped it and made paths entries explicitly relative
("./src/...") so they resolve from tsconfig.json's directory.
Updated both the in-repo tsconfig.json and Task 1 Step 3 in the
plan to match.

Verification: `npm run typecheck` exits 0. Full `npm run dev`
sanity check is deferred until Task 3 (preload) and Task 19
(quickcapture HTML) land — electron-vite.config.ts wires both
entries that don't yet exist.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
altair823
2026-04-25 11:58:59 +09:00
parent 5abec8e7d9
commit 4b16b873c6
6 changed files with 80 additions and 6 deletions

View File

@@ -0,0 +1,46 @@
import { BrowserWindow, app } from 'electron';
import { join } from 'node:path';
import { fileURLToPath } from 'node:url';
let inboxWindow: BrowserWindow | null = null;
const __dirname = fileURLToPath(new URL('.', import.meta.url));
export function getInboxWindow(): BrowserWindow | null {
return inboxWindow;
}
export function createInboxWindow(): BrowserWindow {
if (inboxWindow && !inboxWindow.isDestroyed()) {
inboxWindow.show();
inboxWindow.focus();
return inboxWindow;
}
inboxWindow = new BrowserWindow({
width: 900,
height: 720,
show: false,
webPreferences: {
preload: join(__dirname, '../preload/index.js'),
contextIsolation: true,
nodeIntegration: false,
sandbox: false
}
});
if (process.env.ELECTRON_RENDERER_URL) {
inboxWindow.loadURL(`${process.env.ELECTRON_RENDERER_URL}/inbox/index.html`);
} else {
inboxWindow.loadFile(join(__dirname, '../renderer/inbox/index.html'));
}
inboxWindow.on('close', (e) => {
if (!app.isQuitting) {
e.preventDefault();
inboxWindow?.hide();
}
});
inboxWindow.once('ready-to-show', () => inboxWindow?.show());
return inboxWindow;
}