clawdie-ai/setup/service.ts
2026-03-07 21:55:25 +01:00

110 lines
3 KiB
TypeScript

/**
* Step: service — Build the project and generate FreeBSD start/stop wrappers.
*/
import { execSync } from 'child_process';
import fs from 'fs';
import path from 'path';
import { logger } from '../src/logger.js';
import { getNodePath, getPlatform } from './platform.js';
import { emitStatus } from './status.js';
function writeWrapper(
filePath: string,
contents: string,
mode = 0o755,
): void {
fs.writeFileSync(filePath, contents, { mode });
}
export async function run(_args: string[]): Promise<void> {
const projectRoot = process.cwd();
const platform = getPlatform();
const nodePath = getNodePath();
logger.info({ platform, nodePath, projectRoot }, 'Setting up service');
if (platform !== 'freebsd') {
emitStatus('SETUP_SERVICE', {
SERVICE_TYPE: 'unknown',
NODE_PATH: nodePath,
PROJECT_PATH: projectRoot,
STATUS: 'failed',
ERROR: 'unsupported_platform',
LOG: 'logs/setup.log',
});
process.exit(1);
}
logger.info('Building TypeScript');
try {
execSync('npm run build', {
cwd: projectRoot,
stdio: ['ignore', 'pipe', 'pipe'],
});
} catch {
emitStatus('SETUP_SERVICE', {
SERVICE_TYPE: 'freebsd-wrapper',
NODE_PATH: nodePath,
PROJECT_PATH: projectRoot,
STATUS: 'failed',
ERROR: 'build_failed',
LOG: 'logs/setup.log',
});
process.exit(1);
}
fs.mkdirSync(path.join(projectRoot, 'logs'), { recursive: true });
const pidFile = path.join(projectRoot, 'clawdie.pid');
const startPath = path.join(projectRoot, 'start-clawdie.sh');
const stopPath = path.join(projectRoot, 'stop-clawdie.sh');
writeWrapper(
startPath,
[
'#!/bin/sh',
'set -eu',
`cd ${JSON.stringify(projectRoot)}`,
`if [ -f ${JSON.stringify(pidFile)} ]; then`,
` OLD_PID=$(cat ${JSON.stringify(pidFile)} 2>/dev/null || true)`,
' if [ -n "${OLD_PID:-}" ] && kill -0 "$OLD_PID" 2>/dev/null; then',
' echo "Clawdie is already running" >&2',
' exit 1',
' fi',
'fi',
`nohup ${JSON.stringify(nodePath)} ${JSON.stringify(path.join(projectRoot, 'dist/index.js'))} >> ${JSON.stringify(path.join(projectRoot, 'logs/clawdie.log'))} 2>> ${JSON.stringify(path.join(projectRoot, 'logs/clawdie.error.log'))} &`,
`echo $! > ${JSON.stringify(pidFile)}`,
'echo "Started Clawdie"',
'',
].join('\n'),
);
writeWrapper(
stopPath,
[
'#!/bin/sh',
'set -eu',
`if [ ! -f ${JSON.stringify(pidFile)} ]; then`,
' echo "No PID file found" >&2',
' exit 1',
'fi',
`PID=$(cat ${JSON.stringify(pidFile)})`,
'kill "$PID"',
`rm -f ${JSON.stringify(pidFile)}`,
'echo "Stopped Clawdie"',
'',
].join('\n'),
);
emitStatus('SETUP_SERVICE', {
SERVICE_TYPE: 'freebsd-wrapper',
NODE_PATH: nodePath,
PROJECT_PATH: projectRoot,
START_PATH: startPath,
STOP_PATH: stopPath,
PID_FILE: pidFile,
STATUS: 'success',
LOG: 'logs/setup.log',
});
}