traderclaw-cli 1.0.115 → 1.0.116
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.
|
@@ -1827,12 +1827,13 @@ function configureOpenClawLlmModelPrimaryOnly({ provider, model }, configPath =
|
|
|
1827
1827
|
}
|
|
1828
1828
|
|
|
1829
1829
|
/**
|
|
1830
|
-
* Spawns `openclaw models auth login --provider openai-codex` with a pseudo-TTY when possible.
|
|
1830
|
+
* Spawns `openclaw models auth login --provider openai-codex --method oauth` with a pseudo-TTY when possible.
|
|
1831
|
+
* `--method oauth` skips the interactive Browser vs Device pairing menu (OpenClaw 2026.4.29+); device flow is `device-code`.
|
|
1831
1832
|
* The CLI often exits immediately when stdin/stdout are plain pipes (no TTY). On Unix, `script(1)`
|
|
1832
1833
|
* allocates a PTY so the same flow works as in an interactive terminal.
|
|
1833
1834
|
*/
|
|
1834
1835
|
export function spawnOpenClawCodexAuthLoginChild() {
|
|
1835
|
-
const argv = ["models", "auth", "login", "--provider", "openai-codex"];
|
|
1836
|
+
const argv = ["models", "auth", "login", "--provider", "openai-codex", "--method", "oauth"];
|
|
1836
1837
|
if (process.platform === "win32") {
|
|
1837
1838
|
return spawn("openclaw", argv, { stdio: ["pipe", "pipe", "pipe"], shell: false });
|
|
1838
1839
|
}
|
|
@@ -1846,7 +1847,8 @@ export function spawnOpenClawCodexAuthLoginChild() {
|
|
|
1846
1847
|
// --return propagates openclaw's exit code (util-linux 2.38+).
|
|
1847
1848
|
// -f/--flush: force immediate forwarding of each PTY write to the pipe so the
|
|
1848
1849
|
// wizard sees the URL as soon as OpenClaw prints it (default is block-buffered).
|
|
1849
|
-
const cmdline =
|
|
1850
|
+
const cmdline =
|
|
1851
|
+
"stty cols 32767 rows 50 2>/dev/null; openclaw models auth login --provider openai-codex --method oauth";
|
|
1850
1852
|
return spawn("script", ["--return", "-f", "-q", "-c", cmdline, "/dev/null"], {
|
|
1851
1853
|
stdio: ["pipe", "pipe", "pipe"],
|
|
1852
1854
|
// COLUMNS/LINES: belt-and-suspenders env fallback for programs that read env
|
|
@@ -1859,7 +1861,7 @@ export function spawnOpenClawCodexAuthLoginChild() {
|
|
|
1859
1861
|
}
|
|
1860
1862
|
|
|
1861
1863
|
/**
|
|
1862
|
-
* Runs `openclaw models auth login --provider openai-codex` and feeds the pasted redirect URL or code on stdin
|
|
1864
|
+
* Runs `openclaw models auth login --provider openai-codex --method oauth` and feeds the pasted redirect URL or code on stdin
|
|
1863
1865
|
* when the CLI prompts (with a timed fallback for non-interactive / SSH).
|
|
1864
1866
|
*/
|
|
1865
1867
|
function runOpenClawCodexOAuthLogin(paste, emitLog) {
|
|
@@ -2333,7 +2335,7 @@ export class InstallerStepEngine {
|
|
|
2333
2335
|
} catch (err) {
|
|
2334
2336
|
const tail = `${err?.stderr || ""}\n${err?.stdout || ""}\n${err?.message || ""}`.trim();
|
|
2335
2337
|
throw new Error(
|
|
2336
|
-
`${tail}\n\nIf OAuth cannot complete from the wizard, run in a shell: openclaw models auth login --provider openai-codex — then re-run the wizard with "already logged in" checked.`,
|
|
2338
|
+
`${tail}\n\nIf OAuth cannot complete from the wizard, run in a shell: openclaw models auth login --provider openai-codex --method oauth — then re-run the wizard with "already logged in" checked.`,
|
|
2337
2339
|
);
|
|
2338
2340
|
}
|
|
2339
2341
|
}
|
|
@@ -2347,7 +2349,7 @@ export class InstallerStepEngine {
|
|
|
2347
2349
|
throw new Error(
|
|
2348
2350
|
"No OAuth credentials found at " + authFile + ". " +
|
|
2349
2351
|
"The wizard OAuth flow did not save tokens (the callback may not have reached the OpenClaw CLI). " +
|
|
2350
|
-
"Run 'openclaw models auth login --provider openai-codex' in a terminal, " +
|
|
2352
|
+
"Run 'openclaw models auth login --provider openai-codex --method oauth' in a terminal, " +
|
|
2351
2353
|
"then re-run the wizard with the 'already logged in' option.",
|
|
2352
2354
|
);
|
|
2353
2355
|
}
|
package/bin/openclaw-trader.mjs
CHANGED
|
@@ -3043,7 +3043,11 @@ function wizardHtml(defaults) {
|
|
|
3043
3043
|
setOauthStep(oauthStepOpen, "error");
|
|
3044
3044
|
setOauthStep(oauthStepComplete, "error");
|
|
3045
3045
|
setOauthStep(oauthStepVerify, "error");
|
|
3046
|
-
|
|
3046
|
+
let msg = (data && (data.message || data.error)) || "Could not start OAuth sign-in.";
|
|
3047
|
+
if (data && typeof data.detail === "string" && data.detail.trim()) {
|
|
3048
|
+
msg += " " + data.detail.trim().slice(0, 1500);
|
|
3049
|
+
}
|
|
3050
|
+
setOauthStatus(msg, true);
|
|
3047
3051
|
if (oauthRetryBtn) oauthRetryBtn.classList.remove("hidden");
|
|
3048
3052
|
updateStartButtonState();
|
|
3049
3053
|
return;
|
|
@@ -3629,6 +3633,27 @@ async function cmdInstall(args) {
|
|
|
3629
3633
|
// The \S+ (non-whitespace) tail captures the full query string; see trySendUrl()
|
|
3630
3634
|
// for why we run this against a stripAnsi+CR-stripped copy of the output.
|
|
3631
3635
|
const OPENAI_OAUTH_AUTHORIZE_RE = /https:\/\/auth\.openai\.com\/(?:oauth\/authorize|authorize)[^\s"]*/;
|
|
3636
|
+
const OPENAI_OAUTH_AUTHORIZE_RE_LOOSE =
|
|
3637
|
+
/https:\/\/(?:[a-z0-9-]+\.)*openai\.com\/[^\s"]*?(?:oauth\/authorize|\/authorize[^\s"]*)/i;
|
|
3638
|
+
|
|
3639
|
+
/** Best-effort: primary regex, then subdomain/openai authorize URLs, then token-like query heuristics. */
|
|
3640
|
+
function tryExtractOpenAiCodexAuthorizeUrl(cleaned) {
|
|
3641
|
+
let m = cleaned.match(OPENAI_OAUTH_AUTHORIZE_RE);
|
|
3642
|
+
if (m?.[0]) return m[0];
|
|
3643
|
+
m = cleaned.match(OPENAI_OAUTH_AUTHORIZE_RE_LOOSE);
|
|
3644
|
+
if (m?.[0]) return m[0];
|
|
3645
|
+
const candidates = cleaned.match(/https:\/\/[^\s"]+/g) || [];
|
|
3646
|
+
for (const u of candidates) {
|
|
3647
|
+
if (
|
|
3648
|
+
/openai\.com/i.test(u)
|
|
3649
|
+
&& /authorize/i.test(u)
|
|
3650
|
+
&& /oauth|response_type|client_id|redirect_uri|scope=/i.test(u)
|
|
3651
|
+
) {
|
|
3652
|
+
return u;
|
|
3653
|
+
}
|
|
3654
|
+
}
|
|
3655
|
+
return null;
|
|
3656
|
+
}
|
|
3632
3657
|
const oauthSessionTtlMs = 15 * 60 * 1000;
|
|
3633
3658
|
|
|
3634
3659
|
// Long-lived callback proxy on port 1455. Bound at wizard startup so
|
|
@@ -3856,6 +3881,10 @@ async function cmdInstall(args) {
|
|
|
3856
3881
|
const urlTimeout = setTimeout(() => {
|
|
3857
3882
|
if (responded) return;
|
|
3858
3883
|
responded = true;
|
|
3884
|
+
const detail = stripAnsi(combined).slice(-4000);
|
|
3885
|
+
if (process.env.TRADERCLAW_WIZARD_OAUTH_DEBUG === "1") {
|
|
3886
|
+
printWarn(`[TRADERCLAW_WIZARD_OAUTH_DEBUG] OpenClaw output tail before oauth_url_timeout:\n${detail}`);
|
|
3887
|
+
}
|
|
3859
3888
|
try {
|
|
3860
3889
|
child.kill("SIGTERM");
|
|
3861
3890
|
} catch {
|
|
@@ -3868,6 +3897,7 @@ async function cmdInstall(args) {
|
|
|
3868
3897
|
error: "oauth_url_timeout",
|
|
3869
3898
|
message:
|
|
3870
3899
|
"OpenClaw did not provide a ChatGPT sign-in URL in time. Try again.",
|
|
3900
|
+
detail,
|
|
3871
3901
|
});
|
|
3872
3902
|
}, 120_000);
|
|
3873
3903
|
|
|
@@ -3881,17 +3911,17 @@ async function cmdInstall(args) {
|
|
|
3881
3911
|
const cleanedForUrl = stripAnsi(combined)
|
|
3882
3912
|
.replace(/\r/g, "")
|
|
3883
3913
|
.replace(/([A-Za-z0-9%&=+?#:/@._~!$'()*,;-])\n([A-Za-z0-9%&=+?#:/@._~!$'()*,;-])/g, "$1$2");
|
|
3884
|
-
let
|
|
3914
|
+
let authUrl = tryExtractOpenAiCodexAuthorizeUrl(cleanedForUrl);
|
|
3885
3915
|
// Layer 2: try the raw combined buffer in case stripAnsi dropped a character that
|
|
3886
3916
|
// broke the URL detection (raw ANSI seqs don't include space so regex still works).
|
|
3887
|
-
if (!
|
|
3917
|
+
if (!authUrl) {
|
|
3888
3918
|
const rawCleaned = combined.replace(/\r/g, "")
|
|
3889
3919
|
.replace(/([A-Za-z0-9%&=+?#:/@._~!$'()*,;-])\n([A-Za-z0-9%&=+?#:/@._~!$'()*,;-])/g, "$1$2");
|
|
3890
|
-
|
|
3920
|
+
authUrl = tryExtractOpenAiCodexAuthorizeUrl(rawCleaned);
|
|
3891
3921
|
}
|
|
3892
|
-
if (!
|
|
3922
|
+
if (!authUrl) return;
|
|
3893
3923
|
// Strip any trailing ANSI remnants (e.g. \x1b[0m appended by colour reset)
|
|
3894
|
-
|
|
3924
|
+
authUrl = stripAnsi(authUrl).replace(/\r/g, "").trim();
|
|
3895
3925
|
if (!authUrl.startsWith("https://")) return;
|
|
3896
3926
|
clearTimeout(urlTimeout);
|
|
3897
3927
|
responded = true;
|
|
@@ -3954,7 +3984,7 @@ async function cmdInstall(args) {
|
|
|
3954
3984
|
pending.status = "failed";
|
|
3955
3985
|
pending.message =
|
|
3956
3986
|
"OpenClaw exited OK but no auth tokens were saved. " +
|
|
3957
|
-
"Run 'openclaw models auth login --provider openai-codex' in a terminal, " +
|
|
3987
|
+
"Run 'openclaw models auth login --provider openai-codex --method oauth' in a terminal, " +
|
|
3958
3988
|
"then re-run the wizard with the already-logged-in option.";
|
|
3959
3989
|
} else {
|
|
3960
3990
|
pending.status = "failed";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "traderclaw-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.116",
|
|
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.116"
|
|
21
21
|
},
|
|
22
22
|
"keywords": [
|
|
23
23
|
"traderclaw",
|