traderclaw-cli 1.0.78 → 1.0.79

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.
@@ -1604,14 +1604,14 @@ export function spawnOpenClawCodexAuthLoginChild() {
1604
1604
  if (process.platform === "win32") {
1605
1605
  return spawn("openclaw", argv, { stdio: ["pipe", "pipe", "pipe"], shell: false });
1606
1606
  }
1607
- // `unbuffer` (expect package) runs the CLI under a PTY and forwards stdin for the paste step reliably.
1608
- // Plain `script` often does not forward Node's stdin to the inner openclaw process, which causes hangs until timeout.
1609
1607
  if (commandExists("unbuffer")) {
1610
1608
  return spawn("unbuffer", ["openclaw", ...argv], { stdio: ["pipe", "pipe", "pipe"], shell: false });
1611
1609
  }
1612
1610
  if (commandExists("script")) {
1613
1611
  const cmdline = "openclaw models auth login --provider openai-codex";
1614
- return spawn("script", ["-q", "-c", cmdline, "/dev/null"], {
1612
+ // --return propagates the inner command's exit code (util-linux 2.38+).
1613
+ // Without it, script may exit 0 even if openclaw fails.
1614
+ return spawn("script", ["--return", "-q", "-c", cmdline, "/dev/null"], {
1615
1615
  stdio: ["pipe", "pipe", "pipe"],
1616
1616
  shell: false,
1617
1617
  });
@@ -2093,6 +2093,20 @@ export class InstallerStepEngine {
2093
2093
  }
2094
2094
  }
2095
2095
 
2096
+ const authFile = join(homedir(), ".openclaw", "agents", "main", "agent", "auth-profiles.json");
2097
+ let hasAuth = false;
2098
+ try {
2099
+ hasAuth = readFileSync(authFile, "utf-8").length > 20;
2100
+ } catch { /* file missing */ }
2101
+ if (!hasAuth) {
2102
+ throw new Error(
2103
+ "No OAuth credentials found at " + authFile + ". " +
2104
+ "The wizard OAuth flow did not save tokens (the callback may not have reached the OpenClaw CLI). " +
2105
+ "Run 'openclaw models auth login --provider openai-codex' in a terminal, " +
2106
+ "then re-run the wizard with the 'already logged in' option.",
2107
+ );
2108
+ }
2109
+
2096
2110
  const selection = resolveLlmModelSelection(provider, requestedModel);
2097
2111
  for (const msg of selection.warnings) {
2098
2112
  this.emitLog("configure_llm", "warn", msg);
@@ -3257,6 +3257,32 @@ async function cmdInstall(args) {
3257
3257
  }
3258
3258
  }
3259
3259
 
3260
+ /**
3261
+ * Release port 1455 so the OpenClaw CLI can bind its own callback server
3262
+ * during `openclaw models auth login`. Returns a promise that resolves
3263
+ * once the proxy is fully closed (or after a safety timeout).
3264
+ */
3265
+ function stopCallbackProxy() {
3266
+ return new Promise((resolve) => {
3267
+ if (!oauthCallbackProxy) { resolve(); return; }
3268
+ const proxy = oauthCallbackProxy;
3269
+ oauthCallbackProxy = null;
3270
+ const safety = setTimeout(resolve, 2000);
3271
+ proxy.close(() => { clearTimeout(safety); setTimeout(resolve, 150); });
3272
+ });
3273
+ }
3274
+
3275
+ function hasOpenaiCodexAuthTokens() {
3276
+ try {
3277
+ const authFile = join(homedir(), ".openclaw", "agents", "main", "agent", "auth-profiles.json");
3278
+ const raw = readFileSync(authFile, "utf-8");
3279
+ const data = JSON.parse(raw);
3280
+ return data && typeof data === "object" && JSON.stringify(data).length > 20;
3281
+ } catch {
3282
+ return false;
3283
+ }
3284
+ }
3285
+
3260
3286
  function killOauthSession(sessionId, signal = "SIGTERM") {
3261
3287
  const s = oauthSessions.get(sessionId);
3262
3288
  if (!s) return;
@@ -3388,6 +3414,13 @@ async function cmdInstall(args) {
3388
3414
  killOauthSession(id);
3389
3415
  }
3390
3416
 
3417
+ // Release port 1455 so the OpenClaw CLI can bind its own callback
3418
+ // server directly. The previous approach relied on the wizard proxy
3419
+ // catching the callback and forwarding the code via stdin, but
3420
+ // `script` (PTY wrapper) does not reliably forward stdin to the
3421
+ // inner process, causing tokens to never be saved.
3422
+ await stopCallbackProxy();
3423
+
3391
3424
  const sessionId = randomUUID();
3392
3425
  const child = spawnOpenClawCodexAuthLoginChild();
3393
3426
 
@@ -3402,6 +3435,7 @@ async function cmdInstall(args) {
3402
3435
  /* ignore */
3403
3436
  }
3404
3437
  oauthSessions.delete(sessionId);
3438
+ startCallbackProxy();
3405
3439
  respondJson(504, {
3406
3440
  ok: false,
3407
3441
  error: "oauth_url_timeout",
@@ -3440,6 +3474,7 @@ async function cmdInstall(args) {
3440
3474
  });
3441
3475
  child.on("error", (err) => {
3442
3476
  clearTimeout(urlTimeout);
3477
+ startCallbackProxy();
3443
3478
  if (responded) return;
3444
3479
  responded = true;
3445
3480
  oauthSessions.delete(sessionId);
@@ -3447,6 +3482,7 @@ async function cmdInstall(args) {
3447
3482
  });
3448
3483
  child.on("close", (code) => {
3449
3484
  clearTimeout(urlTimeout);
3485
+ startCallbackProxy();
3450
3486
  if (!responded) {
3451
3487
  responded = true;
3452
3488
  oauthSessions.delete(sessionId);
@@ -3466,9 +3502,15 @@ async function cmdInstall(args) {
3466
3502
  pending.updatedAt = Date.now();
3467
3503
  pending.exitCode = typeof code === "number" ? code : null;
3468
3504
  pending.detail = stripAnsi(combined).slice(-4000);
3469
- if (code === 0) {
3505
+ if (code === 0 && hasOpenaiCodexAuthTokens()) {
3470
3506
  pending.status = "succeeded";
3471
3507
  pending.message = "ChatGPT OAuth completed successfully.";
3508
+ } else if (code === 0) {
3509
+ pending.status = "failed";
3510
+ pending.message =
3511
+ "OpenClaw exited OK but no auth tokens were saved. " +
3512
+ "Run 'openclaw models auth login --provider openai-codex' in a terminal, " +
3513
+ "then re-run the wizard with the already-logged-in option.";
3472
3514
  } else {
3473
3515
  pending.status = "failed";
3474
3516
  pending.message =
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "traderclaw-cli",
3
- "version": "1.0.78",
3
+ "version": "1.0.79",
4
4
  "description": "Global TraderClaw CLI (install --wizard, setup, precheck). Installs solana-traderclaw as a dependency for OpenClaw plugin files.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -17,7 +17,7 @@
17
17
  "node": ">=22"
18
18
  },
19
19
  "dependencies": {
20
- "solana-traderclaw": "^1.0.78"
20
+ "solana-traderclaw": "^1.0.79"
21
21
  },
22
22
  "keywords": [
23
23
  "traderclaw",