clawdie-ai/setup/platform.ts
Sam & Claude 11fbc7f3e0 refactor(phase-2.1): AGENT_NAME namespace — jail-config + platform + jails step
- src/jail-config.ts: full rewrite — drop WARDEN_*/controlplane, introduce
  AGENT_BRIDGE_NAME=clawdie0, AGENT_JAIL_PROFILES, AGENT_SUBNET_*, AGENT_GATEWAY_IP,
  getWorkerBastillePlan(), getDefaultJailConfigForProfile(); all jail names
  derive from process.env.AGENT_NAME (default: clawdie)
- src/jail-config.test.ts: rewrite tests to match new AGENT_* API
- setup/jails.ts: new step replacing jail.ts; creates {AGENT_NAME}-worker jail
  via Bastille using shared clawdie0 bridge
- setup/jail.ts: deleted (replaced by jails.ts)
- setup/index.ts: replace 'jail' step with 'jails', add 'pi-config',
  remove 'network'/'setup-wizard'/'telegram-auth' steps
- setup/platform.ts: add isDesktop() and hasBrowser()
- setup/platform.test.ts: add tests for new functions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 13:47:22 +00:00

79 lines
1.9 KiB
TypeScript

/**
* FreeBSD-focused detection utilities for Clawdie setup.
*/
import { execSync } from 'child_process';
import os from 'os';
export type Platform = 'freebsd' | 'unknown';
export type ServiceManager = 'freebsd-rc' | 'none';
export function getPlatform(): Platform {
return os.platform() === 'freebsd' ? 'freebsd' : 'unknown';
}
export function isRoot(): boolean {
return process.getuid?.() === 0;
}
export function isHeadless(): boolean {
return !process.env.DISPLAY && !process.env.WAYLAND_DISPLAY;
}
/**
* Open a URL or file path in the default browser.
* FreeBSD commonly exposes xdg-open from desktop utilities.
*/
export function openBrowser(target: string): boolean {
if (!commandExists('xdg-open')) return false;
try {
execSync(`xdg-open ${JSON.stringify(target)}`, { stdio: 'ignore' });
return true;
} catch {
return false;
}
}
export function getServiceManager(): ServiceManager {
return getPlatform() === 'freebsd' ? 'freebsd-rc' : 'none';
}
export function getNodePath(): string {
try {
return execSync('command -v node', { encoding: 'utf-8' }).trim();
} catch {
return process.execPath;
}
}
export function commandExists(name: string): boolean {
try {
execSync(`command -v ${name}`, { stdio: 'ignore' });
return true;
} catch {
return false;
}
}
export function getNodeVersion(): string | null {
try {
const version = execSync('node --version', { encoding: 'utf-8' }).trim();
return version.replace(/^v/, '');
} catch {
return process.version ? process.version.replace(/^v/, '') : null;
}
}
export function getNodeMajorVersion(): number | null {
const version = getNodeVersion();
if (!version) return null;
const major = parseInt(version.split('.')[0], 10);
return isNaN(major) ? null : major;
}
export function isDesktop(): boolean {
return !isHeadless();
}
export function hasBrowser(): boolean {
return ['xdg-open', 'firefox', 'chromium', 'chrome'].some(commandExists);
}