diff --git a/CHANGELOG.md b/CHANGELOG.md index 52ea5fc88c5..4bf66995b17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,7 @@ Docs: https://docs.openclaw.ai - CLI/models: use OpenClaw Provider Index preview rows as the final cold fallback for installable providers, while keeping user config, installed manifests, and refreshed cache rows above provider-index metadata. Thanks @vincentkoc. - Providers/plugins: keep onboarding and auth-choice setup lists on cold manifest/install metadata and add Provider Index install metadata for not-yet-installed provider plugins. Thanks @vincentkoc. - Providers/plugins: keep provider setup guidance and configure auth imports on cold manifest metadata, with a regression guard against static provider-runtime imports on setup/configure list paths. Thanks @vincentkoc. +- CLI/capabilities: keep capability command registration from importing the models auth runtime until `model auth login` actually runs. Thanks @vincentkoc. - Plugins/chat commands: refresh the persisted plugin registry after `/plugins enable` and `/plugins disable`, matching the CLI mutation path. Thanks @vincentkoc. - Plugins/compat: mark `OPENCLAW_DISABLE_PERSISTED_PLUGIN_REGISTRY` as a deprecated break-glass switch and point operators at registry repair instead. Thanks @vincentkoc. - Plugins/registry: ignore stale persisted registry reads when plugin policy no longer matches current config, and stamp generated registry files with a do-not-edit warning. Thanks @vincentkoc. diff --git a/src/cli/capability-cli.test.ts b/src/cli/capability-cli.test.ts index be52ac652cc..5e2e1e5c33b 100644 --- a/src/cli/capability-cli.test.ts +++ b/src/cli/capability-cli.test.ts @@ -162,10 +162,13 @@ vi.mock("../agents/memory-search.js", () => ({ mocks.resolveMemorySearchConfig as typeof import("../agents/memory-search.js").resolveMemorySearchConfig, })); -vi.mock("../commands/models.js", () => ({ +vi.mock("../commands/models/auth.js", () => ({ modelsAuthLoginCommand: vi.fn(), +})); + +vi.mock("../commands/models/list.js", () => ({ modelsStatusCommand: - mocks.modelsStatusCommand as typeof import("../commands/models.js").modelsStatusCommand, + mocks.modelsStatusCommand as typeof import("../commands/models/list.js").modelsStatusCommand, })); vi.mock("../gateway/call.js", () => ({ diff --git a/src/cli/capability-cli.ts b/src/cli/capability-cli.ts index 3cc85555d42..8eb73b1d42c 100644 --- a/src/cli/capability-cli.ts +++ b/src/cli/capability-cli.ts @@ -13,7 +13,7 @@ import { import { updateAuthProfileStoreWithLock } from "../agents/auth-profiles/store.js"; import { resolveMemorySearchConfig } from "../agents/memory-search.js"; import { loadModelCatalog } from "../agents/model-catalog.js"; -import { modelsAuthLoginCommand, modelsStatusCommand } from "../commands/models.js"; +import { modelsStatusCommand } from "../commands/models/list.js"; import { loadConfig } from "../config/config.js"; import { resolveAgentModelPrimaryValue } from "../config/model-input.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; @@ -1522,6 +1522,7 @@ export function registerCapabilityCli(program: Command) { .requiredOption("--provider ", "Provider id") .action(async (opts) => { await runCommandWithRuntime(defaultRuntime, async () => { + const { modelsAuthLoginCommand } = await import("../commands/models/auth.js"); await modelsAuthLoginCommand({ provider: String(opts.provider) }, defaultRuntime); }); }); diff --git a/src/cli/model-auth-runtime-boundary.test.ts b/src/cli/model-auth-runtime-boundary.test.ts new file mode 100644 index 00000000000..dd3d9b53b93 --- /dev/null +++ b/src/cli/model-auth-runtime-boundary.test.ts @@ -0,0 +1,16 @@ +import fs from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import { describe, expect, it } from "vitest"; + +const repoRoot = fileURLToPath(new URL("../..", import.meta.url)); + +describe("model auth runtime boundary", () => { + it("keeps capability CLI command registration off the models auth runtime", () => { + const source = fs.readFileSync(path.join(repoRoot, "src/cli/capability-cli.ts"), "utf8"); + + expect(source).not.toMatch(/\bfrom\s+["'][^"']*commands\/models\.js["']/); + expect(source).not.toMatch(/\bfrom\s+["'][^"']*commands\/models\/auth\.js["']/); + expect(source).toMatch(/\bawait\s+import\(["'][^"']*commands\/models\/auth\.js["']\)/); + }); +});