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.
- package/bin/installer-step-engine.mjs +17 -3
- package/bin/openclaw-trader.mjs +43 -1
- package/package.json +2 -2
|
@@ -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
|
|
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);
|
package/bin/openclaw-trader.mjs
CHANGED
|
@@ -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.
|
|
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.
|
|
20
|
+
"solana-traderclaw": "^1.0.79"
|
|
21
21
|
},
|
|
22
22
|
"keywords": [
|
|
23
23
|
"traderclaw",
|