* `clawrouter setup` — finish OpenClaw integration after `npm install -g`. * * Bare `npm install -g @blockrun/clawrouter` puts the package on disk and * adds the `clawrouter` binary to PATH, but performs ZERO OpenClaw plugin * registration: no entry in openclaw.json's `plugins.entries`, no provi
()
| 538 | * complete setup, or after a stuck partial install to repair config. |
| 539 | */ |
| 540 | async function cmdSetup(): Promise<void> { |
| 541 | const { execFileSync, execSync } = await import("node:child_process"); |
| 542 | const { injectModelsConfig, injectAuthProfile } = await import("./index.js"); |
| 543 | |
| 544 | console.log("🦞 ClawRouter setup\n"); |
| 545 | |
| 546 | // Step 1: detect OpenClaw on PATH |
| 547 | let openclawPath: string; |
| 548 | try { |
| 549 | openclawPath = execSync("command -v openclaw", { |
| 550 | encoding: "utf8", |
| 551 | stdio: ["ignore", "pipe", "ignore"], |
| 552 | }).trim(); |
| 553 | if (!openclawPath) throw new Error("not found"); |
| 554 | console.log(` ✓ Found openclaw at ${openclawPath}`); |
| 555 | } catch { |
| 556 | console.error(" ✗ openclaw not found on PATH"); |
| 557 | console.error(" Install OpenClaw first: npm install -g openclaw"); |
| 558 | console.error(" Then re-run: clawrouter setup"); |
| 559 | process.exit(1); |
| 560 | } |
| 561 | |
| 562 | // Step 2: register as an OpenClaw plugin (writes plugins.entries.clawrouter). |
| 563 | // OpenClaw 2026.5.2 added strict validation that may reject our config writes |
| 564 | // during install (e.g. unknown web_search provider blockrun-exa before the |
| 565 | // gateway is running). If that happens, OpenClaw rolls back its own install |
| 566 | // record but our injectModelsConfig step below will still populate the user's |
| 567 | // openclaw.json correctly — they'll just need to re-run `openclaw plugins |
| 568 | // install --force @blockrun/clawrouter` after the gateway has started. |
| 569 | console.log("\n→ Registering ClawRouter with OpenClaw..."); |
| 570 | let installOk = false; |
| 571 | try { |
| 572 | execFileSync(openclawPath, ["plugins", "install", "--force", "@blockrun/clawrouter"], { |
| 573 | stdio: "inherit", |
| 574 | }); |
| 575 | installOk = true; |
| 576 | } catch (err) { |
| 577 | console.warn( |
| 578 | ` ⚠ openclaw plugins install reported a problem: ${err instanceof Error ? err.message : String(err)}`, |
| 579 | ); |
| 580 | console.warn(" Continuing with manual config sync — if validation rejected the install,"); |
| 581 | console.warn( |
| 582 | " re-run `openclaw plugins install --force @blockrun/clawrouter` after gateway start.", |
| 583 | ); |
| 584 | } |
| 585 | |
| 586 | // Step 3: sync the models allowlist + provider config + auth profile directly. |
| 587 | // forceWrite: true bypasses the gateway-mode guard added in v0.12.184 since |
| 588 | // this is an explicit user command, not a plugin-activation hook inside an |
| 589 | // install transaction. |
| 590 | console.log("\n→ Syncing models allowlist + auth profile..."); |
| 591 | const setupLogger = { |
| 592 | info: (msg: string) => console.log(` ${msg}`), |
| 593 | }; |
| 594 | try { |
| 595 | injectModelsConfig(setupLogger, { forceWrite: true }); |
| 596 | injectAuthProfile(setupLogger); |
| 597 | } catch (err) { |
no test coverage detected