Sweep active code, tests, identity files, public docs, CMS seed content, and stale handoffs so old assistant-name fixtures no longer leak into current Clawdie/system-namespace behavior. Keep the skills-memory SQL artifact unchanged per regeneration policy. --- Build: pass Tests: pass — 2197 passed (164 files) --- Build: pass | Tests: pass — 2197 passed (650 files)
138 lines
4.3 KiB
TypeScript
138 lines
4.3 KiB
TypeScript
import { afterEach, describe, it, expect, vi } from 'vitest';
|
|
import fs from 'fs';
|
|
import path from 'path';
|
|
import { execFileSync } from 'child_process';
|
|
|
|
const ENV_KEYS = [
|
|
'PLATFORM_ID',
|
|
'PLATFORM_SERVICE_NAME',
|
|
'PLATFORM_RUNTIME_USER',
|
|
'PLATFORM_RUNTIME_HOME',
|
|
'TENANT_ID',
|
|
] as const;
|
|
|
|
afterEach(() => {
|
|
for (const key of ENV_KEYS) delete process.env[key];
|
|
vi.resetModules();
|
|
});
|
|
|
|
function generateStartWrapper(
|
|
nodePath: string,
|
|
projectRoot: string,
|
|
pidFile: string,
|
|
): string {
|
|
return [
|
|
'#!/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(projectRoot + '/dist/index.js')} >> ${JSON.stringify(projectRoot + '/logs/clawdie.log')} 2>> ${JSON.stringify(projectRoot + '/logs/clawdie.error.log')} &`,
|
|
`echo $! > ${JSON.stringify(pidFile)}`,
|
|
'echo "Started Clawdie"',
|
|
'',
|
|
].join('\n');
|
|
}
|
|
|
|
function generateStopWrapper(pidFile: string): string {
|
|
return [
|
|
'#!/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');
|
|
}
|
|
|
|
describe('FreeBSD wrapper generation', () => {
|
|
it('start wrapper points to dist/index.js', () => {
|
|
const script = generateStartWrapper(
|
|
'/usr/local/bin/node',
|
|
'/home/clawdie/clawdie-ai',
|
|
'/home/clawdie/clawdie-ai/clawdie.pid',
|
|
);
|
|
expect(script).toContain('/home/clawdie/clawdie-ai/dist/index.js');
|
|
});
|
|
|
|
it('start wrapper writes pid file', () => {
|
|
const script = generateStartWrapper(
|
|
'/usr/local/bin/node',
|
|
'/home/clawdie/clawdie-ai',
|
|
'/home/clawdie/clawdie-ai/clawdie.pid',
|
|
);
|
|
expect(script).toContain(
|
|
'echo $! > "/home/clawdie/clawdie-ai/clawdie.pid"',
|
|
);
|
|
});
|
|
|
|
it('stop wrapper removes pid file', () => {
|
|
const script = generateStopWrapper('/home/clawdie/clawdie-ai/clawdie.pid');
|
|
expect(script).toContain('rm -f "/home/clawdie/clawdie-ai/clawdie.pid"');
|
|
});
|
|
|
|
it('resolves platform runtime from constants separately from the tenant', async () => {
|
|
process.env.PLATFORM_ID = 'ignored-platform';
|
|
process.env.PLATFORM_SERVICE_NAME = 'ignored-service';
|
|
process.env.PLATFORM_RUNTIME_USER = 'ignored-user';
|
|
process.env.PLATFORM_RUNTIME_HOME = '/srv/ignored';
|
|
process.env.TENANT_ID = 'alpha';
|
|
|
|
const { resolvePlatformServiceRuntime } =
|
|
await import('../setup/service.js');
|
|
expect(resolvePlatformServiceRuntime()).toEqual({
|
|
serviceName: 'clawdie',
|
|
runtimeUser: 'clawdie',
|
|
runtimeHome: '/home/clawdie',
|
|
});
|
|
});
|
|
|
|
it('generates a shell-valid run wrapper and uses PI_TUI_PROFILE', async () => {
|
|
const { generateRunScript, generateRcdService } =
|
|
await import('../setup/service.js');
|
|
const script = generateRunScript(
|
|
{
|
|
serviceName: 'alpha',
|
|
runtimeUser: 'alpha',
|
|
runtimeHome: '/home/alpha',
|
|
},
|
|
'/usr/local/bin/node',
|
|
'/home/alpha/alpha-ai',
|
|
);
|
|
|
|
expect(script).toContain('PI_TUI_PROFILE');
|
|
expect(script).not.toContain('PI_PROFILE=');
|
|
|
|
const tmpRoot = path.join(process.cwd(), 'tmp');
|
|
fs.mkdirSync(tmpRoot, { recursive: true });
|
|
const tempDir = fs.mkdtempSync(path.join(tmpRoot, 'alpha-service-test-'));
|
|
const scriptPath = path.join(tempDir, 'run-alpha.sh');
|
|
fs.writeFileSync(scriptPath, script, { mode: 0o755 });
|
|
expect(() => execFileSync('sh', ['-n', scriptPath])).not.toThrow();
|
|
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
|
|
const rcd = generateRcdService(
|
|
{
|
|
serviceName: 'alpha',
|
|
runtimeUser: 'alpha',
|
|
runtimeHome: '/home/alpha',
|
|
},
|
|
'/home/alpha/alpha-ai',
|
|
'/home/alpha/alpha-ai/logs/alpha.log',
|
|
);
|
|
|
|
expect(rcd).toContain(
|
|
'command_args="-u alpha -P ${pidfile} -r -f -o \\"/home/alpha/alpha-ai/logs/alpha.log\\" \\"/home/alpha/alpha-ai/run-alpha.sh\\""',
|
|
);
|
|
});
|
|
});
|