Skip to content

Commit 146dba7

Browse files
committed
Merge remote-tracking branch 'origin/main' into claude/clever-kepler-c530ac
2 parents 5bf468e + 3862260 commit 146dba7

19 files changed

Lines changed: 2102 additions & 412 deletions

‎electron/context-window.cjs‎

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const { app, BrowserWindow, dialog, ipcMain } = require('electron');
1+
const { app, BrowserWindow, dialog, ipcMain, screen } = require('electron');
22
const { spawn, spawnSync } = require('node:child_process');
33
const fs = require('node:fs');
44
const http = require('node:http');
@@ -78,8 +78,12 @@ function showWindow(options = {}) {
7878
if (mainWindow.isMinimized()) {
7979
mainWindow.restore();
8080
}
81+
82+
ensureWindowOnVisibleDisplay();
8183
mainWindow.show();
84+
mainWindow.moveTop();
8285
mainWindow.focus();
86+
bringWindowToFront();
8387
const sessionId = typeof options.sessionId === 'string' ? options.sessionId.trim() : '';
8488
const detail = JSON.stringify({ sessionId });
8589
const sessionLiteral = JSON.stringify(sessionId);
@@ -99,6 +103,52 @@ function showWindow(options = {}) {
99103
return true;
100104
}
101105

106+
function ensureWindowOnVisibleDisplay() {
107+
if (!mainWindow) {
108+
return;
109+
}
110+
111+
const bounds = mainWindow.getBounds();
112+
const displays = screen.getAllDisplays();
113+
const intersectsDisplay = displays.some((display) => {
114+
const area = display.workArea;
115+
return (
116+
bounds.x < area.x + area.width &&
117+
bounds.x + bounds.width > area.x &&
118+
bounds.y < area.y + area.height &&
119+
bounds.y + bounds.height > area.y
120+
);
121+
});
122+
123+
if (intersectsDisplay) {
124+
return;
125+
}
126+
127+
const display = screen.getDisplayNearestPoint({ x: 0, y: 0 });
128+
const area = display.workArea;
129+
const width = Math.min(Math.max(bounds.width, MIN_WINDOW_WIDTH), area.width);
130+
const height = Math.min(Math.max(bounds.height, MIN_WINDOW_HEIGHT), area.height);
131+
mainWindow.setBounds(
132+
{
133+
x: Math.round(area.x + (area.width - width) / 2),
134+
y: Math.round(area.y + (area.height - height) / 2),
135+
width,
136+
height,
137+
},
138+
false,
139+
);
140+
writeLog('window was off-screen; moved to nearest display');
141+
}
142+
143+
function bringWindowToFront() {
144+
if (!mainWindow) {
145+
return;
146+
}
147+
148+
mainWindow.setAlwaysOnTop(true, 'screen-saver');
149+
mainWindow.setAlwaysOnTop(false);
150+
}
151+
102152
function startControlServer() {
103153
if (controlServer) {
104154
return;
@@ -340,6 +390,16 @@ async function startFrontend(root) {
340390
writeLog('frontend ready');
341391
}
342392

393+
async function warmContextWorkbenchModels() {
394+
try {
395+
if (await requestOk(BACKEND_PORT, '/api/context-workbench-settings', PROBE_HOST)) {
396+
writeLog('context workbench models refreshed');
397+
}
398+
} catch (error) {
399+
writeLog(`context workbench model refresh skipped: ${error instanceof Error ? error.message : String(error)}`);
400+
}
401+
}
402+
343403
function iconPath(root) {
344404
const iconName = process.platform === 'win32' ? 'hash-icon.ico' : 'hash-icon.png';
345405
const localIcon = path.join(root, 'electron', 'assets', iconName);
@@ -467,6 +527,7 @@ async function boot() {
467527
writeLog(`boot root=${root}`);
468528
await startProxy(root);
469529
await startBackend(root);
530+
await warmContextWorkbenchModels();
470531
if (USE_VITE_FRONTEND) {
471532
await startFrontend(root);
472533
} else {

‎package-lock.json‎

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "hash-context-codex-lab",
3-
"version": "0.6.0",
3+
"version": "0.7.0",
44
"private": true,
55
"description": "Local context proxy and workbench companion for Codex.",
66
"author": "",
@@ -28,7 +28,7 @@
2828
"dev": "vite --config react_app/vite.config.ts",
2929
"dev:react": "vite --config react_app/vite.config.ts",
3030
"typecheck": "tsc -p react_app/tsconfig.json --noEmit",
31-
"test:compact-proxy": "if exist .venv\\Scripts\\python.exe (.venv\\Scripts\\python.exe scripts/test_compact_proxy.py) else (py -3 scripts/test_compact_proxy.py)",
31+
"test:compact-proxy": "node scripts/run-compact-proxy-test.mjs",
3232
"build": "npm run build:react",
3333
"build:react": "vite build --config react_app/vite.config.ts",
3434
"build:python": "node scripts/build-python.mjs",

0 commit comments

Comments
 (0)