traderclaw-cli 1.0.120 → 1.0.121
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 +109 -12
- package/package.json +2 -2
|
@@ -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,11 +633,49 @@ 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
|
+
"--loglevel",
|
|
658
|
+
"info",
|
|
659
|
+
"--registry",
|
|
660
|
+
"https://registry.npmjs.org/",
|
|
661
|
+
`openclaw@${OPENCLAW_VERSION}`,
|
|
662
|
+
],
|
|
663
|
+
{
|
|
664
|
+
onEvent,
|
|
665
|
+
cwd: npmCwd,
|
|
666
|
+
shell: false,
|
|
667
|
+
timeoutMs: effectiveTimeout,
|
|
668
|
+
heartbeatMs: 60_000,
|
|
669
|
+
heartbeatText:
|
|
670
|
+
"npm still installing OpenClaw — if this repeats for a long time, check disk space, DNS, and outbound HTTPS to registry.npmjs.org",
|
|
671
|
+
env: {
|
|
672
|
+
...process.env,
|
|
673
|
+
// Non-interactive / fewer slow npm side trips (fundraising prompts, audit).
|
|
674
|
+
...(process.env.CI ? {} : { CI: "true" }),
|
|
675
|
+
npm_config_update_notifier: process.env.npm_config_update_notifier ?? "false",
|
|
676
|
+
},
|
|
677
|
+
},
|
|
678
|
+
);
|
|
582
679
|
const available = commandExists("openclaw");
|
|
583
680
|
let version = available ? getCommandOutput("openclaw --version", { timeoutMs: OPENCLAW_CLI_VERSION_TIMEOUT_MS }) : null;
|
|
584
681
|
if (available && !version && typeof onEvent === "function") {
|
|
@@ -659,7 +756,7 @@ function isNpmFilesystemPackageSpec(spec) {
|
|
|
659
756
|
* IMPORTANT: run with `{ shell: false }` — `spawn(..., { shell: true })` can drop argv on Unix and npm then mis-resolves the package name.
|
|
660
757
|
*/
|
|
661
758
|
function npmGlobalInstallArgs(spec, { force = false } = {}) {
|
|
662
|
-
const args = ["install", "-g", "--ignore-scripts"];
|
|
759
|
+
const args = ["install", "-g", "--ignore-scripts", "--no-audit", "--no-fund"];
|
|
663
760
|
if (force) args.push("--force");
|
|
664
761
|
if (!isNpmFilesystemPackageSpec(spec)) {
|
|
665
762
|
args.push("--registry", "https://registry.npmjs.org/");
|
|
@@ -2646,7 +2743,7 @@ export class InstallerStepEngine {
|
|
|
2646
2743
|
}
|
|
2647
2744
|
this.emitLog("install_qmd", "info", "Installing @tobilu/qmd globally for vector search memory...");
|
|
2648
2745
|
try {
|
|
2649
|
-
await runCommandWithEvents("npm", ["install", "-g", "--ignore-scripts", "--registry", "https://registry.npmjs.org/", "@tobilu/qmd"], {
|
|
2746
|
+
await runCommandWithEvents("npm", ["install", "-g", "--ignore-scripts", "--no-audit", "--no-fund", "--registry", "https://registry.npmjs.org/", "@tobilu/qmd"], {
|
|
2650
2747
|
onEvent: (evt) => this.emitLog("install_qmd", evt.type === "stderr" ? "warn" : "info", evt.text, evt.urls || []),
|
|
2651
2748
|
});
|
|
2652
2749
|
} 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.121",
|
|
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.121"
|
|
21
21
|
},
|
|
22
22
|
"keywords": [
|
|
23
23
|
"traderclaw",
|