This repository has been archived on 2026-06-01. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
pulse/packages/upulse/src/commands/ui.ts
T
luming 8cf19f58ab feat: upulse ui — local WebUI monitoring dashboard
Add a local WebUI dashboard for monitoring Pulse runtime state.
Run `upulse ui` to start at http://localhost:3140.

Features:
- Dashboard: daemon status, last tick, code rev, recent events timeline
- Vitals: sense key selection, canvas line charts, raw data view
- Rules: engine rule files in onion order
- Deploy: promote/rollback history with active version badge
- Event detail: click any event to view CAS object data

Technical:
- Zero dependencies: Bun HTTP server + single-file embedded HTML
- Linear-inspired dark theme, monospace accents
- 7 API endpoints reading from PulseStore
- Auto-polling (5s) on dashboard
- localhost-only, read-only, no auth needed

Files:
- commands/ui.ts: CLI command registration
- ui/server.ts: Bun HTTP server + API routes
- ui/dashboard.ts: embedded HTML/CSS/JS (874 lines)
- ui/server.test.ts: 8 API tests

Closes #50
2026-04-15 01:02:12 +08:00

47 lines
1.4 KiB
TypeScript

/**
* commands/ui.ts — upulse ui [--port] [--no-open]
*
* Start a local WebUI dashboard for monitoring Pulse.
*/
import type { Command } from 'commander';
import { loadConfig, resolveDir } from '../config.js';
import { createUIServer } from '../ui/server.js';
export function registerUICommand(program: Command): void {
program
.command('ui')
.description('Start local WebUI dashboard')
.option('--port <number>', 'HTTP port', '3140')
.option('--no-open', 'Do not open browser automatically')
.action(async (opts: { port: string; open: boolean }) => {
const config = loadConfig(resolveDir(program.opts().dir));
const port = parseInt(opts.port, 10);
const server = createUIServer(config, port);
console.log(`\n ⚡ Pulse UI running at http://localhost:${port}\n`);
if (opts.open) {
try {
const { execSync } = await import('node:child_process');
const cmd =
process.platform === 'darwin'
? 'open'
: process.platform === 'win32'
? 'start'
: 'xdg-open';
execSync(`${cmd} http://localhost:${port}`, { stdio: 'ignore' });
} catch {
// Ignore — headless environments
}
}
// Keep alive
process.on('SIGINT', () => {
server.stop();
process.exit(0);
});
});
}