@runuai/host 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/cli.ts +28 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@runuai/host",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Uai host — runs ephemeral AI coding tasks in Docker on a machine you control.",
5
5
  "license": "MIT",
6
6
  "author": "Diogo Perillo <diogo.perillo@gmail.com>",
package/src/cli.ts CHANGED
@@ -21,8 +21,9 @@ import "./load-env";
21
21
 
22
22
  import { spawn, spawnSync } from "node:child_process";
23
23
  import { createHash, randomBytes } from "node:crypto";
24
- import { existsSync, readFileSync, writeFileSync } from "node:fs";
24
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
25
25
  import { hostname } from "node:os";
26
+ import { dirname } from "node:path";
26
27
 
27
28
  import { ulid } from "ulid";
28
29
 
@@ -298,9 +299,28 @@ async function cmdSetup(rest: string[]): Promise<void> {
298
299
  return;
299
300
  }
300
301
 
301
- upsertEnvLocal("UAI_HOST_ID", hostId);
302
- upsertEnvLocal("UAI_HOST_TOKEN", secret);
303
- upsertEnvLocal("UAI_CLOUD_URL", cloud);
302
+ // The host is already created on the cloud and the token is spent. If the
303
+ // local write fails, don't lose the secret — print it so it can be saved by
304
+ // hand rather than forcing the user to mint a fresh token.
305
+ try {
306
+ upsertEnvLocal("UAI_HOST_ID", hostId);
307
+ upsertEnvLocal("UAI_HOST_TOKEN", secret);
308
+ upsertEnvLocal("UAI_CLOUD_URL", cloud);
309
+ } catch (err) {
310
+ console.error(
311
+ red(
312
+ `enrolled, but could not write ${envLocalPath()}: ${err instanceof Error ? err.message : String(err)}`,
313
+ ),
314
+ );
315
+ console.error(
316
+ dim("the host exists on the cloud — save these into that file manually, then `uai-host start`:"),
317
+ );
318
+ console.error(` UAI_HOST_ID=${hostId}`);
319
+ console.error(` UAI_HOST_TOKEN=${secret}`);
320
+ console.error(` UAI_CLOUD_URL=${cloud}`);
321
+ process.exitCode = 1;
322
+ return;
323
+ }
304
324
  console.log(green("✓ enrolled") + dim(` — config written to ${envLocalPath()}`));
305
325
  console.log("");
306
326
  console.log("Start the host:");
@@ -326,6 +346,10 @@ async function cmdPair(token: string | undefined): Promise<void> {
326
346
 
327
347
  function upsertEnvLocal(key: string, value: string): void {
328
348
  const path = envLocalPath();
349
+ // UAI_HOME (~/.uai on a fresh install) may not exist yet — create it before
350
+ // the first write, or writeFileSync ENOENTs (which on `setup` would orphan a
351
+ // just-redeemed host + burn the one-time token).
352
+ mkdirSync(dirname(path), { recursive: true });
329
353
  const existing = existsSync(path) ? readFileSync(path, "utf8") : "";
330
354
  const kept = existing
331
355
  .split("\n")