diff --git a/.github/instructions/copilot.instructions.md b/.github/instructions/copilot.instructions.md
index 62bf9f8343bd..03e56ab51277 100644
--- a/.github/instructions/copilot.instructions.md
+++ b/.github/instructions/copilot.instructions.md
@@ -56,7 +56,7 @@
- **Package manager**: pnpm (`pnpm install`)
- **Dev**: `pnpm openclaw ...` or `pnpm dev`
-- **Type-check**: `pnpm tsgo` (core production), `pnpm tsgo:prod` (core + extension production), `pnpm check:test-types` (tests)
+- **Type-check**: `pnpm tsgo` (core production), `pnpm tsgo:prod` (core + UI + extension production), `pnpm check:test-types` (tests)
- **Lint/format**: `pnpm check`
- **Tests**: `pnpm test`
- **Build**: `pnpm build`
diff --git a/.oxlintrc.json b/.oxlintrc.json
index 400d25a53d12..4cfa98d036ff 100644
--- a/.oxlintrc.json
+++ b/.oxlintrc.json
@@ -78,6 +78,7 @@
"typescript/no-empty-object-type": ["error", { "allowInterfaces": "with-single-extends" }],
"typescript/no-explicit-any": "error",
"typescript/no-extraneous-class": "error",
+ "typescript/no-floating-promises": "error",
"typescript/no-import-type-side-effects": "error",
"typescript/no-meaningless-void-operator": "error",
"typescript/no-misused-promises": "error",
@@ -209,15 +210,14 @@
"dist/",
"dist-runtime/",
"docs/_layouts/",
+ "**/a2ui.bundle.js",
"extensions/diffs/assets/viewer-runtime.js",
"extensions/diffs-language-pack/assets/viewer-runtime.js",
- "extensions/canvas/src/host/a2ui/a2ui.bundle.js",
"node_modules/",
"patches/",
"pnpm-lock.yaml",
"skills/**",
"src/auto-reply/reply/export-html/template.js",
- "src/canvas-host/a2ui/a2ui.bundle.js",
"vendor/",
"**/.cache/**",
"**/.openclaw-runtime-deps-copy-*/**",
diff --git a/config/knip.config.ts b/config/knip.config.ts
index 5793c875c343..480f66282b59 100644
--- a/config/knip.config.ts
+++ b/config/knip.config.ts
@@ -145,6 +145,9 @@ const config = {
"@mistralai/mistralai",
"cross-spawn",
"file-type",
+ // Loaded via createRequire in src/agents/utils/syntax-highlight.ts because its
+ // d.ts force-includes lib.dom; knip cannot see the dynamic require.
+ "highlight.js",
"playwright-core",
"partial-json",
"sqlite-vec",
diff --git a/package.json b/package.json
index 6cf27dc76eb3..3b49b2bca33e 100644
--- a/package.json
+++ b/package.json
@@ -1960,7 +1960,7 @@
"tsgo:extensions": "node scripts/run-tsgo.mjs -p tsconfig.extensions.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/extensions.tsbuildinfo",
"tsgo:extensions:all": "node scripts/run-tsgo.mjs -b tsconfig.extensions.projects.json",
"tsgo:extensions:test": "node scripts/run-tsgo.mjs -p test/tsconfig/tsconfig.extensions.test.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/extensions-test.tsbuildinfo",
- "tsgo:prod": "pnpm tsgo:core && pnpm tsgo:extensions",
+ "tsgo:prod": "pnpm tsgo:core && pnpm tsgo:ui && pnpm tsgo:extensions",
"tsgo:profile": "node scripts/profile-tsgo.mjs",
"tsgo:scripts": "node scripts/run-tsgo.mjs -p tsconfig.scripts.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/scripts.tsbuildinfo",
"tsgo:test": "pnpm tsgo:core:test && pnpm tsgo:extensions:test && pnpm tsgo:test:root",
@@ -1969,6 +1969,7 @@
"tsgo:test:root": "node scripts/run-tsgo.mjs -p test/tsconfig/tsconfig.test.root.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/test-root.tsbuildinfo",
"tsgo:test:src": "node scripts/run-tsgo.mjs -p test/tsconfig/tsconfig.test.src.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/test-src.tsbuildinfo",
"tsgo:test:ui": "node scripts/run-tsgo.mjs -p test/tsconfig/tsconfig.test.ui.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/test-ui.tsbuildinfo",
+ "tsgo:ui": "node scripts/run-tsgo.mjs -p tsconfig.ui.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/ui.tsbuildinfo",
"tui": "node scripts/run-node.mjs tui",
"tui:dev": "node scripts/run-with-env.mjs OPENCLAW_PROFILE=dev -- node scripts/run-node.mjs --dev tui",
"tui:pty:test:watch": "node --import tsx scripts/dev/tui-pty-test-watch.ts",
diff --git a/scripts/changed-lanes.d.mts b/scripts/changed-lanes.d.mts
index 7a5beeca546b..e50a00e0bbe4 100644
--- a/scripts/changed-lanes.d.mts
+++ b/scripts/changed-lanes.d.mts
@@ -1,6 +1,7 @@
export type ChangedLane =
| "core"
| "coreTests"
+ | "ui"
| "extensions"
| "extensionTests"
| "scripts"
diff --git a/scripts/changed-lanes.mjs b/scripts/changed-lanes.mjs
index e0741c363246..4386abf0dff9 100644
--- a/scripts/changed-lanes.mjs
+++ b/scripts/changed-lanes.mjs
@@ -12,7 +12,8 @@ const RAW_SYNC_CHANGED_LANES_ENV = "OPENCLAW_CHANGED_LANES_RAW_SYNC";
const DOCS_PATH_RE = /^(?:docs\/|README\.md$|AGENTS\.md$|.*\.mdx?$)/u;
const APP_PATH_RE = /^(?:apps\/|Swabble\/|appcast\.xml$)/u;
const EXTENSION_PATH_RE = /^extensions\/[^/]+(?:\/|$)/u;
-const CORE_PATH_RE = /^(?:src\/|ui\/|packages\/)/u;
+const CORE_PATH_RE = /^(?:src\/|packages\/)/u;
+const UI_PATH_RE = /^(?:ui\/|tsconfig\.ui\.json$)/u;
const SCRIPTS_TYPECHECK_PATH_RE =
/^(?:scripts\/.*\.(?:[cm]?ts|[cm]?tsx)|tsconfig\.scripts\.json)$/u;
const TEST_ROOT_TYPECHECK_PATH_RE =
@@ -58,7 +59,7 @@ export const RELEASE_METADATA_PATHS = new Set([
"package.json",
]);
-/** @typedef {"core" | "coreTests" | "extensions" | "extensionTests" | "scripts" | "testRoot" | "apps" | "docs" | "tooling" | "liveDockerTooling" | "releaseMetadata" | "all"} ChangedLane */
+/** @typedef {"core" | "coreTests" | "ui" | "extensions" | "extensionTests" | "scripts" | "testRoot" | "apps" | "docs" | "tooling" | "liveDockerTooling" | "releaseMetadata" | "all"} ChangedLane */
/**
* @typedef {{
@@ -87,6 +88,7 @@ export function createEmptyChangedLanes() {
return {
core: false,
coreTests: false,
+ ui: false,
extensions: false,
extensionTests: false,
scripts: false,
@@ -218,6 +220,18 @@ export function detectChangedLanes(changedPaths, options = {}) {
continue;
}
+ if (UI_PATH_RE.test(changedPath)) {
+ if (isChangedLaneTestPath(changedPath)) {
+ lanes.coreTests = true;
+ reasons.push(`${changedPath}: UI test`);
+ } else {
+ lanes.ui = true;
+ lanes.coreTests = true;
+ reasons.push(`${changedPath}: UI production`);
+ }
+ continue;
+ }
+
if (APP_PATH_RE.test(changedPath)) {
lanes.apps = true;
reasons.push(`${changedPath}: app surface`);
diff --git a/scripts/check-changed.mjs b/scripts/check-changed.mjs
index c3e3b6c94d2c..5e5474b05332 100644
--- a/scripts/check-changed.mjs
+++ b/scripts/check-changed.mjs
@@ -385,6 +385,9 @@ export function createChangedCheckPlan(result, options = {}) {
if (lanes.coreTests) {
addTypecheck("typecheck core tests", ["tsgo:core:test"]);
}
+ if (lanes.ui) {
+ addTypecheck("typecheck UI", ["tsgo:ui"]);
+ }
if (lanes.extensions) {
addTypecheck("typecheck extensions", ["tsgo:extensions"]);
}
@@ -398,7 +401,7 @@ export function createChangedCheckPlan(result, options = {}) {
addTypecheck("typecheck test root", ["tsgo:test:root"]);
}
- if (lanes.core || lanes.coreTests) {
+ if (lanes.core || lanes.coreTests || lanes.ui) {
const coreLintCommand = createTargetedCoreLintCommand(result.paths, baseEnv);
if (coreLintCommand) {
addCommand(
diff --git a/scripts/check-tsgo-core-boundary.mjs b/scripts/check-tsgo-core-boundary.mjs
index c7771827a54a..50aa0a4f76aa 100644
--- a/scripts/check-tsgo-core-boundary.mjs
+++ b/scripts/check-tsgo-core-boundary.mjs
@@ -10,6 +10,7 @@ const tsgoPath = path.join(repoRoot, "node_modules", ".bin", "tsgo");
const coreGraphs = [
{ name: "core", config: "tsconfig.core.json" },
+ { name: "ui", config: "tsconfig.ui.json" },
{ name: "core-test", config: "test/tsconfig/tsconfig.core.test.json" },
{ name: "core-test-agents", config: "test/tsconfig/tsconfig.core.test.agents.json" },
{ name: "core-test-non-agents", config: "test/tsconfig/tsconfig.core.test.non-agents.json" },
diff --git a/scripts/lib/tsgo-sparse-guard.mjs b/scripts/lib/tsgo-sparse-guard.mjs
index c040a6837cc3..5e6f65a6d736 100644
--- a/scripts/lib/tsgo-sparse-guard.mjs
+++ b/scripts/lib/tsgo-sparse-guard.mjs
@@ -12,14 +12,13 @@ const CORE_TEST_CONFIGS = new Set([
]);
const CORE_PROD_CONFIGS = new Set(["tsconfig.core.json"]);
+const UI_PROD_CONFIGS = new Set(["tsconfig.ui.json"]);
const TSGO_SPARSE_SKIP_ENV_KEY = "OPENCLAW_TSGO_SPARSE_SKIP";
-const CORE_SPARSE_ROOTS = ["packages", "ui/config", "ui/src"];
+const CORE_PROD_SPARSE_ROOTS = ["packages"];
+const UI_PROD_SPARSE_ROOTS = ["packages", "src", "ui/config", "ui/src"];
+const CORE_TEST_SPARSE_ROOTS = ["packages", "ui/config", "ui/src"];
const CORE_PROD_REQUIRED_PATHS = [
- {
- path: "apps/shared/OpenClawKit/Sources/OpenClawKit/Resources/tool-display.json",
- whenPresent: "ui/src/ui/tool-display.ts",
- },
{
path: "scripts/lib/bundled-runtime-sidecar-paths.json",
whenPresent: "src/plugins/runtime-sidecar-paths.ts",
@@ -42,6 +41,13 @@ const CORE_PROD_REQUIRED_PATHS = [
},
];
+const UI_PROD_REQUIRED_PATHS = [
+ {
+ path: "apps/shared/OpenClawKit/Sources/OpenClawKit/Resources/tool-display.json",
+ whenPresent: "ui/src/lib/chat/tool-display.ts",
+ },
+];
+
const CORE_TEST_REQUIRED_PATHS = [
"packages/plugin-package-contract/src/index.ts",
"ui/config/control-ui-chunking.ts",
@@ -85,7 +91,9 @@ export function getSparseTsgoGuardError(
const projectName = projectPath ? path.basename(projectPath) : null;
if (
!projectName ||
- (!CORE_PROD_CONFIGS.has(projectName) && !CORE_TEST_CONFIGS.has(projectName)) ||
+ (!CORE_PROD_CONFIGS.has(projectName) &&
+ !UI_PROD_CONFIGS.has(projectName) &&
+ !CORE_TEST_CONFIGS.has(projectName)) ||
isMetadataOnlyCommand(args)
) {
return null;
@@ -118,8 +126,14 @@ export function getSparseTsgoGuardError(
}
function getRequiredSparseRootsForProject(projectName) {
- if (CORE_PROD_CONFIGS.has(projectName) || CORE_TEST_CONFIGS.has(projectName)) {
- return CORE_SPARSE_ROOTS;
+ if (CORE_PROD_CONFIGS.has(projectName)) {
+ return CORE_PROD_SPARSE_ROOTS;
+ }
+ if (UI_PROD_CONFIGS.has(projectName)) {
+ return UI_PROD_SPARSE_ROOTS;
+ }
+ if (CORE_TEST_CONFIGS.has(projectName)) {
+ return CORE_TEST_SPARSE_ROOTS;
}
return [];
}
@@ -129,6 +143,9 @@ function getRequiredPathsForProject(projectName, cwd, fileExists) {
if (CORE_PROD_CONFIGS.has(projectName)) {
requiredPaths.push(...conditionalRequiredPaths(CORE_PROD_REQUIRED_PATHS, cwd, fileExists));
}
+ if (UI_PROD_CONFIGS.has(projectName)) {
+ requiredPaths.push(...conditionalRequiredPaths(UI_PROD_REQUIRED_PATHS, cwd, fileExists));
+ }
if (CORE_TEST_CONFIGS.has(projectName)) {
requiredPaths.push(...CORE_TEST_REQUIRED_PATHS);
}
diff --git a/scripts/profile-tsgo.mjs b/scripts/profile-tsgo.mjs
index 1dab0771812b..f27503caa7ce 100644
--- a/scripts/profile-tsgo.mjs
+++ b/scripts/profile-tsgo.mjs
@@ -21,6 +21,10 @@ const GRAPH_DEFINITIONS = {
config: "tsconfig.core.json",
description: "core production graph",
},
+ ui: {
+ config: "tsconfig.ui.json",
+ description: "UI production graph",
+ },
"core-test": {
config: "test/tsconfig/tsconfig.core.test.json",
description: "core colocated test graph",
diff --git a/src/agents/code-mode.ts b/src/agents/code-mode.ts
index 3fe293e8b941..bf7831300ddb 100644
--- a/src/agents/code-mode.ts
+++ b/src/agents/code-mode.ts
@@ -807,7 +807,12 @@ export class CodeModeHeadlessTimeoutError extends Error {
}
}
-function createHeadlessAbortScope(signal: AbortSignal | undefined, wallClockMs: number) {
+// Explicit return type: declaration emit cannot name the inferred AbortSignal
+// in the DOM-free core lane (@types/node keeps it in a non-exported module).
+function createHeadlessAbortScope(
+ signal: AbortSignal | undefined,
+ wallClockMs: number,
+): { signal: AbortSignal; cleanup: () => void } {
const controller = new AbortController();
const onAbort = () => controller.abort(signal?.reason);
signal?.addEventListener("abort", onAbort, { once: true });
diff --git a/src/agents/utils/syntax-highlight.ts b/src/agents/utils/syntax-highlight.ts
index 7175ad3dd6c9..2c8a3bfda016 100644
--- a/src/agents/utils/syntax-highlight.ts
+++ b/src/agents/utils/syntax-highlight.ts
@@ -4,9 +4,40 @@
* Highlight.js emits HTML spans; this module walks that small HTML subset and
* maps active scopes to caller-provided text formatters.
*/
-import hljs from "highlight.js";
+import { createRequire } from "node:module";
import { decodeHtmlEntityAt } from "./html.js";
+type HighlightJs = {
+ getLanguage(name: string): unknown;
+ highlight(
+ code: string,
+ options: { language: string; ignoreIllegals?: boolean },
+ ): { value: string };
+ highlightAuto(code: string, languageSubset?: string[]): { value: string };
+};
+
+function isHighlightJs(value: unknown): value is HighlightJs {
+ return (
+ typeof value === "object" &&
+ value !== null &&
+ "getLanguage" in value &&
+ typeof value.getLanguage === "function" &&
+ "highlight" in value &&
+ typeof value.highlight === "function" &&
+ "highlightAuto" in value &&
+ typeof value.highlightAuto === "function"
+ );
+}
+
+// highlight.js ships `/// ` in its d.ts, which would
+// silently re-inject DOM globals into the DOM-free core program. Load it
+// untyped and validate the narrow API we use instead of importing its types.
+const highlightJsModule: unknown = createRequire(import.meta.url)("highlight.js");
+if (!isHighlightJs(highlightJsModule)) {
+ throw new TypeError("highlight.js did not expose the expected Node API");
+}
+const hljs = highlightJsModule;
+
/** Formatter applied to highlighted text segments. */
export type HighlightFormatter = (text: string) => string;
/** Mapping from highlight.js scope names to text formatters. */
diff --git a/src/secrets/config-io.ts b/src/secrets/config-io.ts
index ae9c062c6154..b1aeb40536ca 100644
--- a/src/secrets/config-io.ts
+++ b/src/secrets/config-io.ts
@@ -9,7 +9,9 @@ const silentConfigIoLogger = {
/**
* Creates config I/O for secrets commands with config-loader logging suppressed.
*/
-export function createSecretsConfigIO(params: { env: NodeJS.ProcessEnv }) {
+export function createSecretsConfigIO(params: {
+ env: NodeJS.ProcessEnv;
+}): ReturnType {
// Secrets command output is owned by the CLI command so --json stays machine-parseable.
return createConfigIO({
env: params.env,
diff --git a/src/types/node-runtime-globals.d.ts b/src/types/node-runtime-globals.d.ts
new file mode 100644
index 000000000000..6704154b3f0d
--- /dev/null
+++ b/src/types/node-runtime-globals.d.ts
@@ -0,0 +1,20 @@
+// The core lane compiles with lib ES2023 (no DOM), so these web-global names
+// no longer resolve. Derive them from the fetch globals @types/node already
+// declares (backed by undici) instead of depending on undici-types directly;
+// indexed-access derivation tracks @types/node across upgrades.
+type BodyInit = Exclude;
+type FormDataEntryValue = string | import("node:buffer").File;
+type HeadersInit = Exclude;
+type ReadableStreamReadResult =
+ | import("node:stream/web").ReadableStreamReadDoneResult
+ | import("node:stream/web").ReadableStreamReadValueResult;
+type RequestCredentials = Exclude;
+type RequestInfo = Parameters[0];
+
+// Minimal surface for the one compile() caller; WebAssembly types otherwise
+// live in lib.dom, which the core lane intentionally excludes.
+declare namespace WebAssembly {
+ type Module = object;
+
+ function compile(bytes: ArrayBuffer | ArrayBufferView): Promise;
+}
diff --git a/test/scripts/changed-lanes.test.ts b/test/scripts/changed-lanes.test.ts
index fb506a2fdd8b..237284a01b38 100644
--- a/test/scripts/changed-lanes.test.ts
+++ b/test/scripts/changed-lanes.test.ts
@@ -598,6 +598,31 @@ describe("scripts/changed-lanes", () => {
});
});
+ it("routes UI production changes to UI prod and core test lanes", () => {
+ const result = detectChangedLanes(["ui/src/app.ts"]);
+ const plan = createChangedCheckPlan(result, { env: { PATH: "/usr/bin" } });
+
+ expectLanes(result.lanes, {
+ coreTests: true,
+ ui: true,
+ });
+ expect(plan.commands.map((command) => command.args[0])).toContain("tsgo:ui");
+ expect(plan.commands.map((command) => command.args[0])).toContain("tsgo:core:test");
+ expect(plan.commands.map((command) => command.args[0])).not.toContain("tsgo:core");
+ });
+
+ it("routes the UI production config to UI prod and core test lanes", () => {
+ const result = detectChangedLanes(["tsconfig.ui.json"]);
+ const plan = createChangedCheckPlan(result, { env: { PATH: "/usr/bin" } });
+
+ expectLanes(result.lanes, {
+ coreTests: true,
+ ui: true,
+ });
+ expect(plan.commands.map((command) => command.args[0])).toContain("tsgo:ui");
+ expect(plan.commands.map((command) => command.args[0])).toContain("tsgo:core:test");
+ });
+
it.each([
"scripts/control-ui-i18n.ts",
"scripts/lib/example.ts",
@@ -1851,6 +1876,7 @@ describe("scripts/changed-lanes", () => {
expect(result.lanes).toEqual({
core: false,
coreTests: false,
+ ui: false,
extensions: false,
extensionTests: false,
scripts: false,
diff --git a/test/scripts/oxlint-config.test.ts b/test/scripts/oxlint-config.test.ts
index f877133b3b5e..ec9c7c6d1a92 100644
--- a/test/scripts/oxlint-config.test.ts
+++ b/test/scripts/oxlint-config.test.ts
@@ -140,15 +140,14 @@ describe("oxlint config", () => {
"dist/",
"dist-runtime/",
"docs/_layouts/",
+ "**/a2ui.bundle.js",
"extensions/diffs/assets/viewer-runtime.js",
"extensions/diffs-language-pack/assets/viewer-runtime.js",
- "extensions/canvas/src/host/a2ui/a2ui.bundle.js",
"node_modules/",
"patches/",
"pnpm-lock.yaml",
"skills/**",
"src/auto-reply/reply/export-html/template.js",
- "src/canvas-host/a2ui/a2ui.bundle.js",
"vendor/",
"**/.cache/**",
"**/.openclaw-runtime-deps-copy-*/**",
diff --git a/test/scripts/run-tsgo.test.ts b/test/scripts/run-tsgo.test.ts
index 703e5165e852..fe3e48bb28cc 100644
--- a/test/scripts/run-tsgo.test.ts
+++ b/test/scripts/run-tsgo.test.ts
@@ -111,24 +111,41 @@ describe("run-tsgo sparse guard", () => {
`);
});
- it("returns a helpful message for sparse core worktrees missing transitive project files", () => {
+ it("returns a helpful message for sparse UI worktrees missing transitive project files", () => {
const cwd = createTempDir("openclaw-run-tsgo-");
- const uiToolDisplay = path.join(cwd, "ui/src/ui/tool-display.ts");
+ const uiToolDisplay = path.join(cwd, "ui/src/lib/chat/tool-display.ts");
fs.mkdirSync(path.dirname(uiToolDisplay), { recursive: true });
fs.writeFileSync(uiToolDisplay, "", "utf8");
expect(
- getSparseTsgoGuardError(["-p", "tsconfig.core.json"], {
+ getSparseTsgoGuardError(["-p", "tsconfig.ui.json"], {
cwd,
isSparseCheckoutEnabled: () => true,
}),
).toMatchInlineSnapshot(`
- "tsconfig.core.json cannot be typechecked from this sparse checkout because tracked project inputs are missing or only partially included:
+ "tsconfig.ui.json cannot be typechecked from this sparse checkout because tracked project inputs are missing or only partially included:
- apps/shared/OpenClawKit/Sources/OpenClawKit/Resources/tool-display.json
Expand this worktree's sparse checkout to include those paths, or rerun in a full worktree."
`);
});
+ it("rejects sparse UI worktrees missing the transitive src root", () => {
+ const cwd = createTempDir("openclaw-run-tsgo-");
+
+ expect(
+ getSparseTsgoGuardError(["-p", "tsconfig.ui.json"], {
+ cwd,
+ fileExists: () => true,
+ isSparseCheckoutEnabled: () => true,
+ sparseCheckoutPatterns: ["/packages/", "/ui/config/", "/ui/src/"],
+ }),
+ ).toMatchInlineSnapshot(`
+ "tsconfig.ui.json cannot be typechecked from this sparse checkout because tracked project inputs are missing or only partially included:
+ - src
+ Expand this worktree's sparse checkout to include those paths, or rerun in a full worktree."
+ `);
+ });
+
it("returns a helpful message for sparse core-test worktrees missing ui and packages files", () => {
const cwd = createTempDir("openclaw-run-tsgo-");
diff --git a/tsconfig.core.json b/tsconfig.core.json
index 8f02d04071d3..57283740a1f0 100644
--- a/tsconfig.core.json
+++ b/tsconfig.core.json
@@ -1,10 +1,12 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
+ // Node-side production code must not see browser globals; ui/ owns DOM via tsconfig.ui.json.
+ "lib": ["ES2023"],
"noUnusedLocals": true,
"noUnusedParameters": true,
"tsBuildInfoFile": ".artifacts/tsgo-cache/core.tsbuildinfo"
},
- "include": ["src/**/*", "ui/**/*", "packages/**/*"],
+ "include": ["src/**/*", "packages/**/*"],
"exclude": ["node_modules", "dist", "**/dist/**", "**/*.test.ts", "**/*.test.tsx", "test/**"]
}
diff --git a/tsconfig.core.projects.json b/tsconfig.core.projects.json
index 5c7ff06bae9f..d66561f85d03 100644
--- a/tsconfig.core.projects.json
+++ b/tsconfig.core.projects.json
@@ -2,6 +2,7 @@
"files": [],
"references": [
{ "path": "./tsconfig.core.json" },
+ { "path": "./tsconfig.ui.json" },
{ "path": "./test/tsconfig/tsconfig.core.test.json" }
]
}
diff --git a/tsconfig.ui.json b/tsconfig.ui.json
new file mode 100644
index 000000000000..b767d44eb571
--- /dev/null
+++ b/tsconfig.ui.json
@@ -0,0 +1,10 @@
+{
+ "extends": "./tsconfig.json",
+ "compilerOptions": {
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "tsBuildInfoFile": ".artifacts/tsgo-cache/ui.tsbuildinfo"
+ },
+ "include": ["ui/**/*", "src/**/*.d.ts", "packages/**/*.d.ts"],
+ "exclude": ["node_modules", "dist", "**/dist/**", "**/*.test.ts", "**/*.test.tsx", "test/**"]
+}