@kyleroche/relay 0.2.1 → 0.2.2

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/dist/relay.js +35 -15
  2. package/package.json +1 -1
package/dist/relay.js CHANGED
@@ -9804,6 +9804,13 @@ async function listSiteTools(opts) {
9804
9804
  var tokenLabel = (cfg) => cfg.siteTokenName ?? { device: "an unnamed device-flow token", invite: "an unnamed invite token", manual: "a pasted token", env: "RELAY_TOKEN" }[cfg.siteTokenSource ?? "manual"];
9805
9805
 
9806
9806
  // src/commands/probes.ts
9807
+ var INSTALL_HINT = {
9808
+ claude: "install: npm install -g @anthropic-ai/claude-code (or the macOS pkg from claude.com/code), then run claude and /login",
9809
+ codex: "install: npm install -g @openai/codex, then codex login (or use fx: fx login codex)",
9810
+ fx: "install: the macOS arm64 tarball from https://releases.fx.sh (version in https://releases.fx.sh/latest.txt) into ~/.local/bin, then fx login codex / fx login grok",
9811
+ grok: "install: the grok CLI from x.ai's docs, then grok login (or use fx: fx login grok)",
9812
+ gh: "install: brew install gh, or the macOS pkg from https://github.com/cli/cli/releases/latest, then gh auth login && gh auth setup-git"
9813
+ };
9807
9814
  var PROBE_TOOLS = ["claude", "codex", "fx", "grok", "gh"];
9808
9815
  function run3(bin, args, timeoutMs = 15e3) {
9809
9816
  return new Promise((res) => {
@@ -9856,7 +9863,7 @@ async function probeTools() {
9856
9863
  for (const tool of PROBE_TOOLS) {
9857
9864
  const bin = onPath2(tool);
9858
9865
  if (!bin) {
9859
- checks.push({ status: tool === "gh" || tool === "claude" ? "fail" : "warn", name: `cli:${tool}`, detail: "not on PATH" });
9866
+ checks.push({ status: tool === "gh" || tool === "claude" ? "fail" : "warn", name: `cli:${tool}`, detail: `not on PATH; ${INSTALL_HINT[tool]}` });
9860
9867
  continue;
9861
9868
  }
9862
9869
  checks.push({ status: "ok", name: `cli:${tool}`, detail: bin });
@@ -10236,10 +10243,7 @@ function registerWork(program2, version2, deps = defaultDeps) {
10236
10243
  const c = needContainer();
10237
10244
  const p = plan({ jobs: "1" }, deps, c.bin);
10238
10245
  if (existsSync19(p.path)) {
10239
- for (const w of p.load) {
10240
- const r2 = deps.sh(w);
10241
- if (!r2.ok && !/already|in progress|service already loaded/i.test(r2.out)) throw new Error(`${w.join(" ")} failed: ${r2.out.split("\n")[0] ?? ""}`);
10242
- }
10246
+ loadService(p.load, { tolerateLoaded: true });
10243
10247
  return log2(`service loaded (${p.path}); it runs: ${c.plan.attach.join(" ")}`);
10244
10248
  }
10245
10249
  const r = deps.sh(c.plan.start, { timeoutMs: 12e4 });
@@ -10474,12 +10478,31 @@ ${pad}${r.url}`);
10474
10478
  writeFileSync11(p.path, p.content);
10475
10479
  log2(`wrote ${p.path}`);
10476
10480
  if (deps.platform === "darwin") deps.sh(p.unload[0]);
10477
- for (const w of p.load) {
10481
+ loadService(p.load);
10482
+ log2(`service running; follow it with: tail -f ${p.logPath}; check with: relay work status`);
10483
+ }
10484
+ function loadService(load2, opts = {}) {
10485
+ for (const w of load2) {
10478
10486
  const r = deps.sh(w);
10479
- if (!r.ok) throw new Error(`${w.join(" ")} failed: ${r.out.split("\n")[0] ?? ""}`);
10480
- log2(`ran ${w.join(" ")}`);
10487
+ if (r.ok) {
10488
+ log2(`ran ${w.join(" ")}`);
10489
+ continue;
10490
+ }
10491
+ if (opts.tolerateLoaded && /already|in progress|service already loaded/i.test(r.out)) continue;
10492
+ const guiIdx = w.findIndex((a) => /^gui\/\d+$/.test(a));
10493
+ if (deps.platform === "darwin" && guiIdx >= 0) {
10494
+ const alt = [...w];
10495
+ alt[guiIdx] = w[guiIdx].replace(/^gui\//, "user/");
10496
+ const r2 = deps.sh(alt);
10497
+ if (r2.ok) {
10498
+ log2(`ran ${alt.join(" ")}`);
10499
+ console.log(`note loaded into the user domain: no desktop session for this user (SSH?). It runs while this login lasts; log in on the Mac's screen (or enable automatic login) and re-run relay work --install --yes for the gui domain, which survives logouts.`);
10500
+ continue;
10501
+ }
10502
+ throw new Error(`${w.join(" ")} failed: ${r.out.split("\n")[0] ?? ""} (and user domain: ${r2.out.split("\n")[0] ?? ""}); log in on the Mac's screen as this user once, then re-run`);
10503
+ }
10504
+ throw new Error(`${w.join(" ")} failed: ${r.out.split("\n")[0] ?? ""}`);
10481
10505
  }
10482
- log2(`service running; follow it with: tail -f ${p.logPath}; check with: relay work status`);
10483
10506
  }
10484
10507
  function containerInstallOrRemove(o) {
10485
10508
  if (!o.uninstall) return containerInstall(o, "install");
@@ -10642,11 +10665,7 @@ re-run with --yes to ${mode === "update" ? "rebuild the image, recreate the cont
10642
10665
  mkdirSync15(dirname8(service.logPath), { recursive: true });
10643
10666
  writeFileSync11(service.path, service.content);
10644
10667
  log2(`wrote ${service.path}`);
10645
- for (const w of service.load) {
10646
- const r = deps.sh(w);
10647
- if (!r.ok) throw new Error(`${w.join(" ")} failed: ${r.out.split("\n")[0] ?? ""}`);
10648
- log2(`ran ${w.join(" ")}`);
10649
- }
10668
+ loadService(service.load);
10650
10669
  console.log(`
10651
10670
  ${CONTAINER_NAME} is running ${image} as worker ${workerName}.`);
10652
10671
  printLogins(" ", after2.doctor, "Log in inside:\n");
@@ -10914,6 +10933,7 @@ program.command("usage").option("--days <n>", "window", "7").description("Ledger
10914
10933
  }
10915
10934
  });
10916
10935
  program.parseAsync(process.argv).catch((e) => {
10917
- console.error(e instanceof Error ? e.stack ?? e.message : e);
10936
+ const msg = e instanceof Error ? e.message : String(e);
10937
+ console.error(process.env.RELAY_DEBUG && e instanceof Error ? e.stack ?? msg : `relay: ${msg}`);
10918
10938
  process.exit(1);
10919
10939
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kyleroche/relay",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "relay: your coding-agent subscriptions (Claude Code, Codex, Grok) as one system. The CLI, the session hooks and the memory MCP server.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",