fix(cli): apply biome lint fixes and remove old MJS files

Apply biome auto-fixes:
- Sort imports: move type imports first in urec.ts and uconn.ts
- Remove inferrable type annotations (stdoutBuf, stderrBuf, backoff)

Complete migration:
- Delete old urec.mjs and uconn.mjs files

All biome checks now pass with no errors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-28 10:20:09 +00:00
parent 0c3624ddca
commit 12343b05ae
4 changed files with 5 additions and 179 deletions
-117
View File
@@ -1,117 +0,0 @@
#!/usr/bin/env node
import { mkdir, readFile, readdir, stat, unlink, writeFile } from "node:fs/promises";
import { homedir, hostname } from "node:os";
import { join } from "node:path";
import { MSG } from "@uncaged/dashboard-server/protocol";
import { watch } from "chokidar";
import { program } from "commander";
import { WebSocket } from "ws";
program.option("--url <url>", "WebSocket URL", "wss://dashboard.shazhou.work/ws/worker").parse();
const opts = program.opts();
const WS_URL = opts.url;
const DEVICE = hostname();
const RECORDS_DIR = join(homedir(), ".uwf-dashboard/records");
const SYNCED_FILE = join(homedir(), ".uwf-dashboard/.synced");
const THREE_DAYS = 3 * 24 * 60 * 60 * 1000;
await mkdir(RECORDS_DIR, { recursive: true });
let synced = new Set();
let ws = null;
let pendingRecords = [];
let backoff = 1000;
const MAX_BACKOFF = 30000;
async function loadSynced() {
try {
const data = await readFile(SYNCED_FILE, "utf8");
synced = new Set(data.split("\n").filter(Boolean));
} catch {
synced = new Set();
}
}
async function saveSynced() {
await writeFile(SYNCED_FILE, [...synced].join("\n"));
}
async function cleanOldRecords() {
try {
const files = await readdir(RECORDS_DIR);
const now = Date.now();
for (const f of files) {
if (!f.endsWith(".json")) continue;
const fp = join(RECORDS_DIR, f);
const s = await stat(fp);
if (now - s.mtimeMs > THREE_DAYS) {
await unlink(fp).catch(() => {});
synced.delete(f.replace(".json", ""));
}
}
await saveSynced();
} catch {}
}
async function sendRecord(filePath) {
try {
const data = await readFile(filePath, "utf8");
const record = JSON.parse(data);
if (synced.has(record.id)) return;
if (ws?.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({ type: MSG.RECORD, record }));
synced.add(record.id);
await saveSynced();
} else {
pendingRecords.push(filePath);
}
} catch {}
}
async function syncAll() {
try {
const files = await readdir(RECORDS_DIR);
for (const f of files) {
if (!f.endsWith(".json")) continue;
await sendRecord(join(RECORDS_DIR, f));
}
} catch {}
}
function connect() {
console.log(`Connecting to ${WS_URL}...`);
ws = new WebSocket(WS_URL);
ws.on("open", () => {
console.log("Connected to dashboard server");
backoff = 1000;
ws.send(JSON.stringify({ type: MSG.REGISTER, device: DEVICE }));
syncAll();
const pending = [...pendingRecords];
pendingRecords = [];
for (const f of pending) sendRecord(f);
});
ws.on("close", () => {
console.log(`Disconnected. Reconnecting in ${backoff / 1000}s...`);
setTimeout(connect, backoff);
backoff = Math.min(backoff * 2, MAX_BACKOFF);
});
ws.on("error", (err) => {
console.error("WebSocket error:", err.message);
ws.close();
});
}
await loadSynced();
await cleanOldRecords();
setInterval(cleanOldRecords, 60 * 60 * 1000);
connect();
const watcher = watch(RECORDS_DIR, {
ignoreInitial: true,
awaitWriteFinish: { stabilityThreshold: 300 },
});
watcher.on("add", (fp) => {
if (fp.endsWith(".json")) sendRecord(fp);
});
+2 -2
View File
@@ -3,7 +3,7 @@ import { mkdir, readFile, readdir, stat, unlink, writeFile } from "node:fs/promi
import { homedir, hostname } from "node:os";
import { join } from "node:path";
import { MSG } from "@uncaged/dashboard-server/protocol";
import { watch, type FSWatcher } from "chokidar";
import { type FSWatcher, watch } from "chokidar";
import { program } from "commander";
import { WebSocket } from "ws";
@@ -34,7 +34,7 @@ await mkdir(RECORDS_DIR, { recursive: true });
let synced: Set<string> = new Set();
let ws: WebSocket | null = null;
let pendingRecords: string[] = [];
let backoff: number = 1000;
let backoff = 1000;
const MAX_BACKOFF: number = 30000;
async function loadSynced(): Promise<void> {
-57
View File
@@ -1,57 +0,0 @@
#!/usr/bin/env node
import { spawn } from "node:child_process";
import { randomUUID } from "node:crypto";
import { mkdir, writeFile } from "node:fs/promises";
import { homedir, hostname } from "node:os";
import { join } from "node:path";
const RECORDS_DIR = join(homedir(), ".uwf-dashboard/records");
await mkdir(RECORDS_DIR, { recursive: true });
const args = process.argv.slice(2);
if (args.length === 0) {
console.error("Usage: urec <command> [args...]");
process.exit(1);
}
const command = args.join(" ");
const id = randomUUID();
const device = hostname();
const startedAt = new Date().toISOString();
let stdoutBuf = "";
let stderrBuf = "";
const child = spawn(args[0], args.slice(1), { stdio: ["inherit", "pipe", "pipe"] });
child.stdout.on("data", (d) => {
const s = d.toString();
process.stdout.write(s);
stdoutBuf += s;
});
child.stderr.on("data", (d) => {
const s = d.toString();
process.stderr.write(s);
stderrBuf += s;
});
const signals = ["SIGINT", "SIGTERM"];
for (const sig of signals) process.on(sig, () => child.kill(sig));
child.on("close", async (exitCode) => {
const finishedAt = new Date().toISOString();
const durationMs = new Date(finishedAt) - new Date(startedAt);
const record = {
id,
device,
command,
args: args.slice(1),
stdout: stdoutBuf,
stderr: stderrBuf,
exitCode: exitCode ?? 1,
startedAt,
finishedAt,
durationMs,
};
await writeFile(join(RECORDS_DIR, `${id}.json`), JSON.stringify(record, null, 2));
process.exit(exitCode ?? 1);
});
+3 -3
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env node
import { spawn, type ChildProcess } from "node:child_process";
import { type ChildProcess, spawn } from "node:child_process";
import { randomUUID } from "node:crypto";
import { mkdir, writeFile } from "node:fs/promises";
import { homedir, hostname } from "node:os";
@@ -31,8 +31,8 @@ const command: string = args.join(" ");
const id: string = randomUUID();
const device: string = hostname();
const startedAt: string = new Date().toISOString();
let stdoutBuf: string = "";
let stderrBuf: string = "";
let stdoutBuf = "";
let stderrBuf = "";
const child: ChildProcess = spawn(args[0], args.slice(1), { stdio: ["inherit", "pipe", "pipe"] });