directlx-claude-config/plans/iridescent-coalescing-charm.md

124 lines
5.1 KiB
Markdown

# HiveOps Browser — System Info Footer Status Bar
## Context
The HiveOps Browser (Electron 28) currently loads `https://incident.bcos.cloud` directly in the main `BrowserWindow`. The user wants a persistent footer status bar — native to the browser chrome like a menu/status bar — showing: logged-in user, memory usage, CPU usage, and service health. This replaces the fragile approach of having the Svelte frontend call `electronAPI.getUserProfile()`.
## Architecture Change
**Current**: `BrowserWindow``loadURL('https://incident.bcos.cloud')` (fills full window)
**New**: `BrowserWindow` (no content) →
- `WebContentsView` (top, full width, `height - 32px`) → `loadURL('https://incident.bcos.cloud')`
- `WebContentsView` (bottom, full width, `32px`) → `loadFile('src/renderer/statusbar.html')`
Electron 28's `WebContentsView` API is used (replaces deprecated `BrowserView`).
---
## Files to Modify / Create
### 1. `src/main/preload.js` — Add 2 new IPC bindings
```javascript
getSystemInfo: () => ipcRenderer.invoke('get-system-info'),
getServiceStatus: () => ipcRenderer.invoke('get-service-status'),
```
### 2. `src/main/main.js` — Major changes
- Import `WebContentsView` from electron
- Create `incidentView` (WebContentsView with preload) and `statusbarView` (WebContentsView with preload)
- Replace `mainWindow.loadURL(allowedUrl)` with:
- `mainWindow.contentView.addChildView(incidentView)``incidentView.webContents.loadURL(allowedUrl)`
- `mainWindow.contentView.addChildView(statusbarView)``statusbarView.webContents.loadFile('statusbar.html')`
- Migrate all `mainWindow.webContents.*` event listeners to `incidentView.webContents.*`:
- `did-finish-load`, `dom-ready`, `console-message`, `did-fail-load`, `page-title-updated`, `will-navigate`
- Move session header injection to `incidentView.webContents.session.webRequest.onBeforeSendHeaders`
- Add `mainWindow.on('resize', updateBounds)` to keep views sized correctly
- Add `updateBounds()` helper: sets incidentView to `{x:0, y:0, w, h-32}` and statusbarView to `{x:0, y:h-32, w, h:32}`
- Add new IPC handlers:
- `get-system-info` → uses Node `os` module: `{ memory: {used, total, percent}, cpu: {load}, user: authManager.getUserInfo() }`
- `get-service-status` → pings health endpoints with `net.request()`, returns array of `{name, status: 'up'|'down'|'checking'}`
### 3. `src/renderer/statusbar.html` — New file
Compact 32px dark status bar with 3 sections:
```
[ 👤 John Doe ADMIN ] ──── [ RAM 52% ████░░ 4.2/8GB ] [ CPU 23% ] ──── [ ● Auth ● Incident ● Config ] ──── [ v2.0.40 ]
```
- Dark background `#0f0f1a` with subtle top border `rgba(255,255,255,0.08)`
- White/muted text, monospace for metrics
- Service dots: green `●` = up, red `●` = down, yellow `●` = checking
- Uses `window.electronAPI.getSystemInfo()` + `getServiceStatus()` on load and every 5s
- Memory: inline bar visualization
- No external dependencies (pure HTML/CSS/JS)
### Service Health Endpoints (defaults, from known architecture)
```javascript
const SERVICE_ENDPOINTS = [
{ name: 'Auth', url: `${authServerUrl}/actuator/health` },
{ name: 'Incident', url: `${allowedUrl}/actuator/health` },
{ name: 'Config', url: `${apiBaseUrl.replace('/api/v1','')}/actuator/health` },
];
```
These use the existing config values. Timeout: 3s. Returns up/down per service.
---
## Key Technical Details
### WebContentsView bounds management
```javascript
function updateBounds() {
const STATUS_BAR_H = 32;
const [w, h] = mainWindow.getContentSize();
incidentView.setBounds({ x: 0, y: 0, width: w, height: h - STATUS_BAR_H });
statusbarView.setBounds({ x: 0, y: h - STATUS_BAR_H, width: w, height: STATUS_BAR_H });
}
mainWindow.on('resize', updateBounds);
```
### Header injection moves to incidentView's session
```javascript
incidentView.webContents.session.webRequest.onBeforeSendHeaders(...)
```
### System info IPC handler
```javascript
const os = require('os');
ipcMain.handle('get-system-info', () => {
const total = os.totalmem();
const free = os.freemem();
const used = total - free;
const [load1] = os.loadavg(); // Linux/Mac; 0 on Windows
return {
memory: { used, total, percent: Math.round((used / total) * 100) },
cpu: { load: Math.min(100, Math.round(load1 * 100 / os.cpus().length)) },
user: authManager.getUserInfo(),
version: app.getVersion(),
};
});
```
### Service status uses electron net module
```javascript
const { net } = require('electron');
// HEAD request with 3s timeout per service
```
---
## Cleanup
- Remove `getUserProfile` call from `hiveops-incident/frontend/src/App.svelte` (the sidebar-user block) since user info is now shown in the browser's own status bar.
---
## Build & Verify
1. `cd /source/hiveops-src/hiveops-browser && npm start` — dev test
2. Confirm status bar appears at bottom of window
3. Confirm incident app fills remaining space and works normally
4. Confirm user name/role shows (must be logged in)
5. Confirm memory/CPU metrics update every 5s
6. Confirm service dots show correct status
7. `npm run build:linux` — build production package
8. Test with `dist/linux-unpacked/hiveops-browser --no-sandbox`