refactor: extract shared runCommand utility and cleanup codebase

- Create shared command utility in ts/utils/command.ts
- Update index.ts, process-manager.ts, system-info.ts to use shared utility
- Remove duplicate runCommand implementations from all files
- Remove legacy Chrome wrapper methods (startChrome, stopChrome, isChromeRunning)
- Consolidate Sway window selectors from 5 to 2
- Remove unused isobuild TypeScript files (mod.ts, deno.json, ts/index.ts)
- Make getStatus() async to properly await system info
- Add disk and system info sections to UI
This commit is contained in:
2026-01-08 16:31:57 +00:00
parent 1435496a1c
commit 3fb8b14e41
9 changed files with 87 additions and 438 deletions

View File

@@ -7,6 +7,7 @@
import { ProcessManager } from './process-manager.ts';
import { SystemInfo } from './system-info.ts';
import { UIServer } from '../ui/server.ts';
import { runCommand } from '../utils/command.ts';
export interface DaemonConfig {
uiPort: number;
@@ -60,13 +61,14 @@ export class EcoDaemon {
return [...this.logs];
}
getStatus(): Record<string, unknown> {
async getStatus(): Promise<Record<string, unknown>> {
const systemInfo = await this.systemInfo.getInfo();
return {
sway: this.swayStatus.state === 'running',
swayStatus: this.swayStatus,
chromium: this.chromiumStatus.state === 'running',
chromiumStatus: this.chromiumStatus,
systemInfo: this.systemInfo.getInfo(),
systemInfo,
logs: this.logs.slice(-50),
};
}
@@ -166,14 +168,14 @@ export class EcoDaemon {
}
private async ensureSeatd(): Promise<void> {
const status = await this.runCommand('systemctl', ['is-active', 'seatd']);
const status = await runCommand('systemctl', ['is-active', 'seatd']);
if (status.success && status.stdout.trim() === 'active') {
this.log('seatd is already running');
return;
}
this.log('Starting seatd service...');
const result = await this.runCommand('systemctl', ['start', 'seatd']);
const result = await runCommand('systemctl', ['start', 'seatd']);
if (!result.success) {
this.log('Warning: Failed to start seatd: ' + result.stderr);
}
@@ -184,9 +186,9 @@ export class EcoDaemon {
// Ensure XDG_RUNTIME_DIR exists
const runtimeDir = `/run/user/${uid}`;
await this.runCommand('mkdir', ['-p', runtimeDir]);
await this.runCommand('chown', [`${this.config.user}:${this.config.user}`, runtimeDir]);
await this.runCommand('chmod', ['700', runtimeDir]);
await runCommand('mkdir', ['-p', runtimeDir]);
await runCommand('chown', [`${this.config.user}:${this.config.user}`, runtimeDir]);
await runCommand('chmod', ['700', runtimeDir]);
if (mode === 'drm') {
this.log('Starting Sway with DRM backend (hardware rendering)');
@@ -243,31 +245,13 @@ export class EcoDaemon {
}
private async getUserUid(): Promise<number> {
const result = await this.runCommand('id', ['-u', this.config.user]);
const result = await runCommand('id', ['-u', this.config.user]);
if (!result.success) {
throw new Error('Failed to get user UID: ' + result.stderr);
}
return parseInt(result.stdout.trim(), 10);
}
private async runCommand(
cmd: string,
args: string[]
): Promise<{ success: boolean; stdout: string; stderr: string }> {
const command = new Deno.Command(cmd, {
args,
stdout: 'piped',
stderr: 'piped',
});
const result = await command.output();
return {
success: result.success,
stdout: new TextDecoder().decode(result.stdout),
stderr: new TextDecoder().decode(result.stderr),
};
}
private async runForever(): Promise<void> {
// Monitor processes and restart if needed
while (true) {