feat(cli): implement CLI entry point with auto-daemon launcher (Task 18)

- Add auto-daemon.ts: ensureDaemonRunning() checks health, reads pidfile,
  spawns daemon if needed, polls health up to 3s
- Rewrite index.ts: commander-based CLI with all subcommands (health,
  open, list, get, kill, navigate, click, type, scroll, eval, wait,
  screenshot, text, html, profiles)
- Add daemon project reference to cli tsconfig
This commit is contained in:
AskaEth committed 2026-08-12 21:24:07 +08:00
1 parent 4f387b5ae7
commit b843eea9ae
3 files changed
+206 -3

No files matched your search

+39
View File
@@ -0,0 +1,39 @@
import { spawn } from 'node:child_process';
import path from 'node:path';
import { readPidfile, isProcessAlive } from '@visionl/daemon/dist/pidfile.js';
import { VisionLClient } from '@visionl/core';
const POLL_INTERVAL_MS = 100;
const MAX_WAIT_MS = 3000;
export async function ensureDaemonRunning(port: number): Promise<VisionLClient> {
const client = new VisionLClient(`http://127.0.0.1:${port}`);
if (await client.health()) {
return client;
}
const pidInfo = readPidfile();
if (pidInfo && isProcessAlive(pidInfo.pid)) {
if (await client.health()) {
return client;
}
}
const daemonEntryPath = path.resolve(__dirname, '../../daemon/dist/server.js');
spawn('node', [daemonEntryPath], {
env: { ...process.env, VISIONL_PORT: String(port) },
stdio: 'ignore',
detached: true,
}).unref();
const startTime = Date.now();
while (Date.now() - startTime < MAX_WAIT_MS) {
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
if (await client.health()) {
return client;
}
}
throw new Error('DAEMON_UNREACHABLE');
}