diff --git a/config/knip.config.ts b/config/knip.config.ts index 0f4b2dbb59ac..af5250cc985e 100644 --- a/config/knip.config.ts +++ b/config/knip.config.ts @@ -162,7 +162,6 @@ const config = { entry: [ "index.html!", "src/main.ts!", - "src/build/chunking.ts!", "vite.config.ts!", "vitest*.ts!", ], diff --git a/scripts/deadcode-unused-files.allowlist.mjs b/scripts/deadcode-unused-files.allowlist.mjs index 6f3a96ebb79a..3d89c5a67505 100644 --- a/scripts/deadcode-unused-files.allowlist.mjs +++ b/scripts/deadcode-unused-files.allowlist.mjs @@ -42,5 +42,4 @@ export const KNIP_OPTIONAL_UNUSED_FILE_ALLOWLIST = [ "extensions/qa-lab/src/auth-profile.fixture.ts", "extensions/qa-lab/src/codex-plugin.fixture.ts", "src/gateway/test/server-sessions-helpers.ts", - "ui/src/ui/control-ui-chunking.ts", ]; diff --git a/scripts/lib/tsgo-sparse-guard.mjs b/scripts/lib/tsgo-sparse-guard.mjs index fb0dbe71283f..94d131f06e39 100644 --- a/scripts/lib/tsgo-sparse-guard.mjs +++ b/scripts/lib/tsgo-sparse-guard.mjs @@ -12,7 +12,7 @@ const CORE_TEST_CONFIGS = new Set([ const CORE_PROD_CONFIGS = new Set(["tsconfig.core.json"]); const TSGO_SPARSE_SKIP_ENV_KEY = "OPENCLAW_TSGO_SPARSE_SKIP"; -const CORE_SPARSE_ROOTS = ["packages", "ui/src"]; +const CORE_SPARSE_ROOTS = ["packages", "ui/config", "ui/src"]; const CORE_PROD_REQUIRED_PATHS = [ { @@ -43,6 +43,7 @@ const CORE_PROD_REQUIRED_PATHS = [ const CORE_TEST_REQUIRED_PATHS = [ "packages/plugin-package-contract/src/index.ts", + "ui/config/control-ui-chunking.ts", "ui/src/i18n/lib/registry.ts", "ui/src/i18n/lib/types.ts", "ui/src/ui/app-settings.ts", diff --git a/scripts/test-projects.test-support.mjs b/scripts/test-projects.test-support.mjs index b140146369eb..5f4b4ecf8629 100644 --- a/scripts/test-projects.test-support.mjs +++ b/scripts/test-projects.test-support.mjs @@ -560,7 +560,7 @@ const GENERATED_CHANGED_TEST_TARGET_PATTERNS = [ /^extensions\/[^/]+\/src\/host\/.+\/\.bundle\.hash$/u, /^extensions\/[^/]+\/src\/host\/.+\/[^/]+\.bundle\.js$/u, ]; -const SOURCE_ROOTS_FOR_IMPORT_GRAPH = ["src", "extensions", "packages", "ui/src", "test"]; +const SOURCE_ROOTS_FOR_IMPORT_GRAPH = ["src", "extensions", "packages", "ui/src", "ui/config", "test"]; const IMPORTABLE_FILE_EXTENSIONS = [".ts", ".tsx", ".mts", ".cts"]; const IMPORT_SPECIFIER_PATTERN = /\b(?:import|export)\s+(?:type\s+)?(?:[^'"]*?\s+from\s+)?["']([^"']+)["']|\bimport\s*\(\s*["']([^"']+)["']\s*\)/gu; @@ -1285,7 +1285,7 @@ function resolvePreciseChangedTestTargets(changedPath, options) { if (siblingTest) { return [siblingTest]; } - if (/^(?:src|test\/helpers|extensions|packages|ui\/src)\//u.test(changedPath)) { + if (/^(?:src|test\/helpers|extensions|packages|ui\/src|ui\/config)\//u.test(changedPath)) { const affectedTests = resolveAffectedTestsFromImportGraph(changedPath, cwd); if (affectedTests.length > 0) { return affectedTests; diff --git a/test/scripts/run-tsgo.test.ts b/test/scripts/run-tsgo.test.ts index dfc341285459..700d83e12d6a 100644 --- a/test/scripts/run-tsgo.test.ts +++ b/test/scripts/run-tsgo.test.ts @@ -48,6 +48,7 @@ describe("run-tsgo sparse guard", () => { const cwd = createTempDir("openclaw-run-tsgo-"); const requiredPaths = [ "packages/plugin-package-contract/src/index.ts", + "ui/config/control-ui-chunking.ts", "ui/src/i18n/lib/registry.ts", "ui/src/i18n/lib/types.ts", "ui/src/ui/app-settings.ts", @@ -65,7 +66,7 @@ describe("run-tsgo sparse guard", () => { getSparseTsgoGuardError(["-p", "test/tsconfig/tsconfig.core.test.non-agents.json"], { cwd, isSparseCheckoutEnabled: () => true, - sparseCheckoutPatterns: ["/packages/", "/ui/src/"], + sparseCheckoutPatterns: ["/packages/", "/ui/config/", "/ui/src/"], }), ).toBeNull(); }); @@ -74,6 +75,7 @@ describe("run-tsgo sparse guard", () => { const cwd = createTempDir("openclaw-run-tsgo-"); const requiredPaths = [ "packages/plugin-package-contract/src/index.ts", + "ui/config/control-ui-chunking.ts", "ui/src/i18n/lib/registry.ts", "ui/src/i18n/lib/types.ts", "ui/src/ui/app-settings.ts", @@ -92,6 +94,7 @@ describe("run-tsgo sparse guard", () => { isSparseCheckoutEnabled: () => true, sparseCheckoutPatterns: [ "/packages/plugin-package-contract/src/index.ts", + "/ui/config/control-ui-chunking.ts", "/ui/src/i18n/lib/registry.ts", "/ui/src/i18n/lib/types.ts", "/ui/src/ui/app-settings.ts", @@ -101,6 +104,7 @@ describe("run-tsgo sparse guard", () => { ).toMatchInlineSnapshot(` "tsconfig.core.test.json cannot be typechecked from this sparse checkout because tracked project inputs are missing or only partially included: - packages + - ui/config - ui/src Expand this worktree's sparse checkout to include those paths, or rerun in a full worktree." `); @@ -135,6 +139,7 @@ describe("run-tsgo sparse guard", () => { ).toMatchInlineSnapshot(` "tsconfig.core.test.json cannot be typechecked from this sparse checkout because tracked project inputs are missing or only partially included: - packages/plugin-package-contract/src/index.ts + - ui/config/control-ui-chunking.ts - ui/src/i18n/lib/registry.ts - ui/src/i18n/lib/types.ts - ui/src/ui/app-settings.ts diff --git a/test/scripts/test-projects.test.ts b/test/scripts/test-projects.test.ts index 561db203e395..03ad1a5c77cd 100644 --- a/test/scripts/test-projects.test.ts +++ b/test/scripts/test-projects.test.ts @@ -570,6 +570,21 @@ describe("scripts/test-projects changed-target routing", () => { ]); }); + it("routes changed ui build helpers to their importing tests", () => { + const plans = buildVitestRunPlans(["--changed", "origin/main"], process.cwd(), () => [ + "ui/config/control-ui-chunking.ts", + ]); + + expect(plans).toEqual([ + { + config: "test/vitest/vitest.ui.config.ts", + forwardedArgs: [], + includePatterns: ["ui/src/ui/control-ui-chunking.test.ts"], + watchMode: false, + }, + ]); + }); + it("routes unit ui test targets to the unit ui lane", () => { expect(buildVitestRunPlans(["ui/src/ui/chat/grouped-render.test.ts"])).toEqual([ { diff --git a/ui/src/build/chunking.ts b/ui/config/control-ui-chunking.ts similarity index 100% rename from ui/src/build/chunking.ts rename to ui/config/control-ui-chunking.ts diff --git a/ui/src/ui/control-ui-chunking.test.ts b/ui/src/ui/control-ui-chunking.test.ts index 0529a1432a44..198d9092caf0 100644 --- a/ui/src/ui/control-ui-chunking.test.ts +++ b/ui/src/ui/control-ui-chunking.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from "vitest"; -import { controlUiManualChunk, normalizeModuleId } from "../build/chunking.ts"; +import { controlUiManualChunk, normalizeModuleId } from "../../config/control-ui-chunking.ts"; describe("Control UI build chunking", () => { it("groups stable runtime dependencies into bounded chunks", () => { diff --git a/ui/vite.config.ts b/ui/vite.config.ts index 146b0df5171a..6ec209f76a37 100644 --- a/ui/vite.config.ts +++ b/ui/vite.config.ts @@ -3,7 +3,7 @@ import fs from "node:fs"; import path from "node:path"; import { fileURLToPath } from "node:url"; import { defineConfig, type Plugin } from "vite"; -import { controlUiManualChunk } from "./src/build/chunking.ts"; +import { controlUiManualChunk } from "./config/control-ui-chunking.ts"; const here = path.dirname(fileURLToPath(import.meta.url)); const repoRoot = path.resolve(here, "..");