traderclaw-cli 1.0.120 → 1.0.122
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 +118 -15
- package/package.json +2 -2
|
@@ -11,7 +11,7 @@ const CONFIG_DIR = join(homedir(), ".openclaw");
|
|
|
11
11
|
const CONFIG_FILE = join(CONFIG_DIR, "openclaw.json");
|
|
12
12
|
|
|
13
13
|
/** Pinned openclaw platform version — bump deliberately after testing, never use "latest". */
|
|
14
|
-
export const OPENCLAW_VERSION = "2026.4
|
|
14
|
+
export const OPENCLAW_VERSION = "2026.5.4";
|
|
15
15
|
|
|
16
16
|
/** Directory containing solana-traderclaw (openclaw.plugin.json) — works for plugin layout or traderclaw-cli + dependency. */
|
|
17
17
|
const PLUGIN_PACKAGE_ROOT = resolvePluginPackageRoot(import.meta.url);
|
|
@@ -451,7 +451,25 @@ function isOpenClawConfigSchemaFailure(text) {
|
|
|
451
451
|
|
|
452
452
|
function runCommandWithEvents(cmd, args = [], opts = {}) {
|
|
453
453
|
return new Promise((resolve, reject) => {
|
|
454
|
-
const {
|
|
454
|
+
const {
|
|
455
|
+
onEvent,
|
|
456
|
+
timeoutMs = 0,
|
|
457
|
+
heartbeatMs = 0,
|
|
458
|
+
heartbeatText = "command still running…",
|
|
459
|
+
...spawnOpts
|
|
460
|
+
} = opts;
|
|
461
|
+
|
|
462
|
+
let settled = false;
|
|
463
|
+
let timeoutId;
|
|
464
|
+
let heartbeatId;
|
|
465
|
+
const finish = (fn, arg) => {
|
|
466
|
+
if (settled) return;
|
|
467
|
+
settled = true;
|
|
468
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
469
|
+
if (heartbeatId) clearInterval(heartbeatId);
|
|
470
|
+
fn(arg);
|
|
471
|
+
};
|
|
472
|
+
|
|
455
473
|
const isNpm = /(?:^|[\\/])npm(?:\.cmd)?$/.test(cmd) || cmd === "npm";
|
|
456
474
|
if (isNpm && !spawnOpts.env?.NODE_OPTIONS?.includes("max-old-space-size")) {
|
|
457
475
|
spawnOpts.env = {
|
|
@@ -471,6 +489,44 @@ function runCommandWithEvents(cmd, args = [], opts = {}) {
|
|
|
471
489
|
const emitFn = typeof onEvent === "function" ? onEvent : null;
|
|
472
490
|
const emit = (event) => emitFn && emitFn(event);
|
|
473
491
|
|
|
492
|
+
if (typeof timeoutMs === "number" && timeoutMs > 0) {
|
|
493
|
+
timeoutId = setTimeout(() => {
|
|
494
|
+
try {
|
|
495
|
+
child.kill("SIGTERM");
|
|
496
|
+
} catch {
|
|
497
|
+
/* ignore */
|
|
498
|
+
}
|
|
499
|
+
setTimeout(() => {
|
|
500
|
+
try {
|
|
501
|
+
child.kill("SIGKILL");
|
|
502
|
+
} catch {
|
|
503
|
+
/* ignore */
|
|
504
|
+
}
|
|
505
|
+
}, 12_000);
|
|
506
|
+
const tail = `${stdout}\n${stderr}`.trim().slice(-6000);
|
|
507
|
+
const err = new Error(
|
|
508
|
+
`Timed out after ${timeoutMs}ms: ${cmd} ${args.join(" ")}\n`
|
|
509
|
+
+ `Last output:\n${tail || "(no output yet — possible npm registry or network stall; try again or run the same npm command in a terminal)"}`,
|
|
510
|
+
);
|
|
511
|
+
err.timedOut = true;
|
|
512
|
+
err.stdout = stdout;
|
|
513
|
+
err.stderr = stderr;
|
|
514
|
+
finish(reject, err);
|
|
515
|
+
}, timeoutMs);
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
if (typeof heartbeatMs === "number" && heartbeatMs > 0 && emitFn) {
|
|
519
|
+
const start = Date.now();
|
|
520
|
+
heartbeatId = setInterval(() => {
|
|
521
|
+
const sec = Math.floor((Date.now() - start) / 1000);
|
|
522
|
+
emitFn({
|
|
523
|
+
type: "stdout",
|
|
524
|
+
text: `[installer] ${heartbeatText} (${sec}s elapsed).\n`,
|
|
525
|
+
urls: [],
|
|
526
|
+
});
|
|
527
|
+
}, heartbeatMs);
|
|
528
|
+
}
|
|
529
|
+
|
|
474
530
|
child.stdout?.on("data", (d) => {
|
|
475
531
|
const text = d.toString();
|
|
476
532
|
stdout += text;
|
|
@@ -484,8 +540,9 @@ function runCommandWithEvents(cmd, args = [], opts = {}) {
|
|
|
484
540
|
});
|
|
485
541
|
|
|
486
542
|
child.on("close", (code) => {
|
|
543
|
+
if (settled) return;
|
|
487
544
|
const urls = [...new Set([...extractUrls(stdout), ...extractUrls(stderr)])];
|
|
488
|
-
if (code === 0) resolve
|
|
545
|
+
if (code === 0) finish(resolve, { stdout, stderr, code, urls });
|
|
489
546
|
else {
|
|
490
547
|
const isOom = code === 137 || (stderr || stdout || "").includes("Killed");
|
|
491
548
|
const raw = (stderr || "").trim();
|
|
@@ -500,10 +557,10 @@ function runCommandWithEvents(cmd, args = [], opts = {}) {
|
|
|
500
557
|
err.stderr = stderr;
|
|
501
558
|
err.urls = urls;
|
|
502
559
|
err.oom = isOom;
|
|
503
|
-
reject
|
|
560
|
+
finish(reject, err);
|
|
504
561
|
}
|
|
505
562
|
});
|
|
506
|
-
child.on("error", reject);
|
|
563
|
+
child.on("error", (e) => finish(reject, e));
|
|
507
564
|
});
|
|
508
565
|
}
|
|
509
566
|
|
|
@@ -535,7 +592,7 @@ export async function ensureOpenClawGlobalPackageDependencies() {
|
|
|
535
592
|
return { skipped: true, reason: "global_openclaw_dir_not_found" };
|
|
536
593
|
}
|
|
537
594
|
const registry = "https://registry.npmjs.org/";
|
|
538
|
-
const installFlags = ["install", "--omit=dev", "--ignore-scripts", "--registry", registry];
|
|
595
|
+
const installFlags = ["install", "--omit=dev", "--ignore-scripts", "--no-audit", "--no-fund", "--registry", registry];
|
|
539
596
|
await runCommandWithEvents("npm", installFlags, { cwd: dir, shell: false });
|
|
540
597
|
await runCommandWithEvents(
|
|
541
598
|
"npm",
|
|
@@ -544,6 +601,8 @@ export async function ensureOpenClawGlobalPackageDependencies() {
|
|
|
544
601
|
"--omit=dev",
|
|
545
602
|
"--no-save",
|
|
546
603
|
"--ignore-scripts",
|
|
604
|
+
"--no-audit",
|
|
605
|
+
"--no-fund",
|
|
547
606
|
"--registry",
|
|
548
607
|
registry,
|
|
549
608
|
"grammy",
|
|
@@ -574,17 +633,61 @@ async function installOpenClawPlatform(onEvent) {
|
|
|
574
633
|
});
|
|
575
634
|
}
|
|
576
635
|
const npmCwd = getNpmGlobalInstallCwd();
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
636
|
+
const npmTimeoutMs = Number.parseInt(String(process.env.TRADERCLAW_OPENCLAW_NPM_TIMEOUT_MS || "").trim(), 10);
|
|
637
|
+
const effectiveTimeout = Number.isFinite(npmTimeoutMs) && npmTimeoutMs > 0 ? npmTimeoutMs : 1_800_000;
|
|
638
|
+
if (typeof onEvent === "function") {
|
|
639
|
+
onEvent({
|
|
640
|
+
type: "stdout",
|
|
641
|
+
text:
|
|
642
|
+
`Running: npm install -g openclaw@${OPENCLAW_VERSION} (cwd=${npmCwd}, --no-audit --no-fund). `
|
|
643
|
+
+ "First-time or upgrade installs can take several minutes; live npm lines and heartbeats appear below. "
|
|
644
|
+
+ `Also watch the terminal where you started \`traderclaw install --wizard\`. `
|
|
645
|
+
+ `Override stall limit: TRADERCLAW_OPENCLAW_NPM_TIMEOUT_MS (ms), default ${effectiveTimeout}.\n`,
|
|
646
|
+
urls: [],
|
|
647
|
+
});
|
|
648
|
+
}
|
|
649
|
+
await runCommandWithEvents(
|
|
650
|
+
"npm",
|
|
651
|
+
[
|
|
652
|
+
"install",
|
|
653
|
+
"-g",
|
|
654
|
+
"--ignore-scripts",
|
|
655
|
+
"--no-audit",
|
|
656
|
+
"--no-fund",
|
|
657
|
+
"--prefer-offline",
|
|
658
|
+
"--loglevel",
|
|
659
|
+
"warn",
|
|
660
|
+
"--registry",
|
|
661
|
+
"https://registry.npmjs.org/",
|
|
662
|
+
`openclaw@${OPENCLAW_VERSION}`,
|
|
663
|
+
],
|
|
664
|
+
{
|
|
665
|
+
onEvent,
|
|
666
|
+
cwd: npmCwd,
|
|
667
|
+
shell: false,
|
|
668
|
+
timeoutMs: effectiveTimeout,
|
|
669
|
+
heartbeatMs: 30_000,
|
|
670
|
+
heartbeatText:
|
|
671
|
+
"npm still installing OpenClaw (extract/link phase — this is normal silence). Check disk space and outbound HTTPS to registry.npmjs.org if this repeats many times",
|
|
672
|
+
env: {
|
|
673
|
+
...process.env,
|
|
674
|
+
// Non-interactive / fewer slow npm side trips (fundraising prompts, audit).
|
|
675
|
+
...(process.env.CI ? {} : { CI: "true" }),
|
|
676
|
+
npm_config_update_notifier: process.env.npm_config_update_notifier ?? "false",
|
|
677
|
+
},
|
|
678
|
+
},
|
|
679
|
+
);
|
|
680
|
+
if (typeof onEvent === "function") {
|
|
681
|
+
onEvent({ type: "stdout", text: "npm install -g openclaw completed. Verifying binary on PATH…\n", urls: [] });
|
|
682
|
+
}
|
|
582
683
|
const available = commandExists("openclaw");
|
|
583
|
-
|
|
684
|
+
// Version check is informational only — cap it tightly so a blocking CLI startup never stalls the step.
|
|
685
|
+
const VERSION_TIMEOUT_MS = 8_000;
|
|
686
|
+
let version = available ? getCommandOutput("openclaw --version", { timeoutMs: VERSION_TIMEOUT_MS }) : null;
|
|
584
687
|
if (available && !version && typeof onEvent === "function") {
|
|
585
688
|
onEvent({
|
|
586
689
|
type: "stderr",
|
|
587
|
-
text:
|
|
690
|
+
text: `openclaw is on PATH but --version did not respond within ${VERSION_TIMEOUT_MS}ms; treating install as successful.\n`,
|
|
588
691
|
urls: [],
|
|
589
692
|
});
|
|
590
693
|
version = "(version check timed out)";
|
|
@@ -659,7 +762,7 @@ function isNpmFilesystemPackageSpec(spec) {
|
|
|
659
762
|
* IMPORTANT: run with `{ shell: false }` — `spawn(..., { shell: true })` can drop argv on Unix and npm then mis-resolves the package name.
|
|
660
763
|
*/
|
|
661
764
|
function npmGlobalInstallArgs(spec, { force = false } = {}) {
|
|
662
|
-
const args = ["install", "-g", "--ignore-scripts"];
|
|
765
|
+
const args = ["install", "-g", "--ignore-scripts", "--no-audit", "--no-fund"];
|
|
663
766
|
if (force) args.push("--force");
|
|
664
767
|
if (!isNpmFilesystemPackageSpec(spec)) {
|
|
665
768
|
args.push("--registry", "https://registry.npmjs.org/");
|
|
@@ -2646,7 +2749,7 @@ export class InstallerStepEngine {
|
|
|
2646
2749
|
}
|
|
2647
2750
|
this.emitLog("install_qmd", "info", "Installing @tobilu/qmd globally for vector search memory...");
|
|
2648
2751
|
try {
|
|
2649
|
-
await runCommandWithEvents("npm", ["install", "-g", "--ignore-scripts", "--registry", "https://registry.npmjs.org/", "@tobilu/qmd"], {
|
|
2752
|
+
await runCommandWithEvents("npm", ["install", "-g", "--ignore-scripts", "--no-audit", "--no-fund", "--registry", "https://registry.npmjs.org/", "@tobilu/qmd"], {
|
|
2650
2753
|
onEvent: (evt) => this.emitLog("install_qmd", evt.type === "stderr" ? "warn" : "info", evt.text, evt.urls || []),
|
|
2651
2754
|
});
|
|
2652
2755
|
} catch (err) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "traderclaw-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.122",
|
|
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.122"
|
|
21
21
|
},
|
|
22
22
|
"keywords": [
|
|
23
23
|
"traderclaw",
|