#!/usr/bin/env node
import { spawn } from "node:child_process";
import { setTimeout as delay } from "node:timers/promises";
const env = {
...process.env,
AWS_ACCESS_KEY_ID: process.env.AWS_ACCESS_KEY_ID || "local",
AWS_SECRET_ACCESS_KEY: process.env.AWS_SECRET_ACCESS_KEY || "local",
AWS_REGION: process.env.AWS_REGION || "us-east-1",
CELLD_WORKER_LOADER: process.env.CELLD_WORKER_LOADER || "LOADER",
CELLD_WATCH: process.env.CELLD_WATCH || ".celld-state",
};
for (const name of ["CLOUDFLARE_ACCOUNT_ID", "CLOUDFLARE_API_TOKEN"]) {
const value = process.env[`CELLD_VAR_${name}`] || process.env[name];
if (value) env[`CELLD_VAR_${name}`] = value;
}
const children = new Set();
function start(name, command, args, options = {}) {
const child = spawn(command, args, {
stdio: "inherit",
env,
shell: process.platform === "win32",
...options,
});
children.add(child);
child.on("exit", (code, signal) => {
children.delete(child);
if (!options.allowExit && code !== 0) {
console.error(`${name} exited with ${signal || code}`);
shutdown(code || 1);
}
});
return child;
}
function run(name, command, args) {
return new Promise((resolve, reject) => {
const child = start(name, command, args, { allowExit: true });
child.on("exit", (code) =>
code === 0 ? resolve() : reject(new Error(`${name} exited ${code}`)),
);
});
}
function shutdown(code = 0) {
for (const child of children) child.kill("SIGTERM");
setTimeout(() => process.exit(code), 200).unref();
}
process.on("SIGINT", () => shutdown(130));
process.on("SIGTERM", () => shutdown(143));
start("local-s3-shim", process.execPath, [
"script/local-s3-shim.mjs",
"--root",
".celld-s3",
"--port",
"9000",
]);
await delay(300);
await run("celld deploy", "celld", [
"deploy",
".",
"--bucket",
"s3://celld-computer",
"--endpoint",
"http://127.0.0.1:9000",
"--region",
"us-east-1",
]);
if (!env.CELLD_VAR_CLOUDFLARE_ACCOUNT_ID || !env.CELLD_VAR_CLOUDFLARE_API_TOKEN) {
console.warn(
"Cloudflare credentials are unset; the agent can connect, but model requests will fail.",
);
}
start("celld", "celld", [
"--bucket",
"s3://celld-computer",
"--endpoint",
"http://127.0.0.1:9000",
"--region",
"us-east-1",
"--listen",
"127.0.0.1:8080",
"--advertise",
"127.0.0.1:8080",
]);
console.log("\ncelld is starting on http://127.0.0.1:8080");
console.log("Open the terminal client with `npm run chat`.\n");