mirror of
https://github.com/Darkatse/TauriTavern.git
synced 2026-10-19 15:45:12 +00:00
build(frontend): remove Vue toolchain
This commit is contained in:
parent
1bd7d6e399
commit
72ff45bd15
6 changed files with 29 additions and 179 deletions
|
|
@ -211,9 +211,7 @@ TauriTavern 自有的状态型 UI 作为 SillyTavern first-party extension 挂
|
|||
- 样式必须使用 `--SmartTheme*`、字体、动画与边框变量,保留 SillyTavern vanilla 视觉和用户主题覆盖能力。
|
||||
- `tsconfig.ui.json`、React Hooks/TypeScript lint 与 Rstest/Testing Library 显式覆盖 Agent、MCP 和 `src/scripts/tauri/setting` 三个 owned scope;`pnpm check` 是统一验收入口。
|
||||
- production 与 development 共用 `createRspackConfigs(mode)`。标准 Tauri dev server 在首次 development 编译成功后才监听,并只在成功重编译后 reload。
|
||||
- `scripts/check-first-party-ui-guardrails.mjs` 约束 runtime template、Vue import、Vue root 和新 TSX 文件尺寸只能随迁移收敛。
|
||||
|
||||
自有 UI 的 Vue root 已清零;不得重新引入跨框架组件桥。Vue dependency 与残留构建配置在独立清理阶段删除,不与功能改动混合。
|
||||
- `scripts/check-first-party-ui-guardrails.mjs` 为自有扩展架构限定为 React + Strict TypeScript。
|
||||
当前工程基线、冻结 handle 与 bundle 数据见 `docs/CurrentState/FirstPartyUI.md`。
|
||||
|
||||
### 7.4 契约与约束
|
||||
|
|
|
|||
|
|
@ -87,7 +87,6 @@ TauriTavern 将 SillyTavern 1.18.0 前端移植到 Tauri v2 原生应用中,
|
|||
| DOMPurify | HTML 净化 |
|
||||
| Highlight.js | 代码高亮 |
|
||||
| localForage | 浏览器侧存储 |
|
||||
| Vue | 自有 UI 已不再消费;依赖与残留构建配置待独立清理 |
|
||||
| React / React DOM | TauriTavern first-party 状态型 UI 的统一表示层 |
|
||||
| strict TypeScript / TSX | React presentation、typed actions 与组件测试 |
|
||||
|
||||
|
|
@ -156,7 +155,7 @@ pnpm run check:rust:dev
|
|||
|
||||
- `scripts/check-rust-crate-boundaries.mjs` 守住 Rust crate 依赖方向。
|
||||
- `scripts/check-frontend-guardrails.mjs` 守住前端注入层边界。
|
||||
- `scripts/check-first-party-ui-guardrails.mjs` 守住自有 UI 的 Vue 退役棘轮。
|
||||
- `scripts/check-first-party-ui-guardrails.mjs` 守住 React + strict TS/TSX 边界。
|
||||
- `scripts/check-logging-boundaries.mjs` 守住 logging target 使用边界。
|
||||
- `tsconfig.host.json` 为 Host Kernel 提供 TypeScript 检查。
|
||||
- `tsconfig.ui.json` 为 Agent、MCP 与 Tauri Settings owned UI 提供 strict TS/TSX 检查。
|
||||
|
|
|
|||
|
|
@ -93,7 +93,6 @@
|
|||
"react-dom": "^19.2.8",
|
||||
"seedrandom": "^3.0.5",
|
||||
"showdown": "^2.1.0",
|
||||
"vue": "^3.5.41",
|
||||
"yaml": "^2.8.3"
|
||||
},
|
||||
"engines": {
|
||||
|
|
|
|||
137
pnpm-lock.yaml
generated
137
pnpm-lock.yaml
generated
|
|
@ -83,9 +83,6 @@ importers:
|
|||
showdown:
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0
|
||||
vue:
|
||||
specifier: ^3.5.41
|
||||
version: 3.5.41(typescript@5.9.3)
|
||||
yaml:
|
||||
specifier: ^2.8.3
|
||||
version: 2.8.3
|
||||
|
|
@ -723,33 +720,6 @@ packages:
|
|||
resolution: {integrity: sha512-fkv8dHRDqfGtTHuJeebdrQ7cX6Ad4WAS00rgHh9UGvMycF1mjBfsxry1XsLIFhWZ6Judlh6UdzK+TYlbpCXgnA==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@vue/compiler-core@3.5.41':
|
||||
resolution: {integrity: sha512-q0Xtv/F9w2YO/7htQhtiL+Ev2WCJbe5N2hc+XfgyKkEKqWpSxknmT8QOuGdEKNdjPq0c3F7rNpFkTo3Kfrm7pg==}
|
||||
|
||||
'@vue/compiler-dom@3.5.41':
|
||||
resolution: {integrity: sha512-oKacVfNglLvGjnS6BXOlGL7EyG2h8X03pqXCjzotRZUaXGjbrTJUnVAQjrCqUnS+lyu31nwQjZY/d817GmCnfw==}
|
||||
|
||||
'@vue/compiler-sfc@3.5.41':
|
||||
resolution: {integrity: sha512-XJhip7R2wy6vX3knCxdZN4KracFaZUef58s1KYewqluedHIJaPIVfXoYT7MF1F8nCvv6k8bWWxDC8opMkg1VTQ==}
|
||||
|
||||
'@vue/compiler-ssr@3.5.41':
|
||||
resolution: {integrity: sha512-U3v5OejKEGqOI0Wy0+Sz7hGuIFZHA4LSXzrNM3IMIeDyJEBBfTpX26n3SDgToRpP2bLc9FfI2j/kSgcJ8Emq5A==}
|
||||
|
||||
'@vue/reactivity@3.5.41':
|
||||
resolution: {integrity: sha512-rznsqKM0np0x18EjzF8x88MpEhdNsffbvFbckLL5+oUKz1BxAImEmO7J1ArRYSyo6aQaVoBDp7jEkT91OOxydA==}
|
||||
|
||||
'@vue/runtime-core@3.5.41':
|
||||
resolution: {integrity: sha512-Vcry58hiAKwGen9Z1jUZE0feFsNArPCMOImYI8el48A9Idf6DuQYD0U05zZIF2Iad1hGhPSvcbBbAOhNr55fhg==}
|
||||
|
||||
'@vue/runtime-dom@3.5.41':
|
||||
resolution: {integrity: sha512-3vVBahVBS9+U6cmXBLyb8nE6/yYo4J/CGI9eVFs3KiMc0YHuudwKyShTD65jtJy/L9PUUxNAFu4cj4LiJ0UFbw==}
|
||||
|
||||
'@vue/server-renderer@3.5.41':
|
||||
resolution: {integrity: sha512-n6hx/pNFfbD6SuyeuMVkvqox8bwf/ET9JlA/kAz/imw8sw++wkqKe2mHX5KutjPpbKE4Z56yTHszoOjGMI9igQ==}
|
||||
|
||||
'@vue/shared@3.5.41':
|
||||
resolution: {integrity: sha512-IOnwSCma8j+9xJT6b8H0dEYidC80NsYmNMlZxRsukYcSoGaDBohog5hDxzeUXdFeGWFA++vWvxqOmrr96VlqMA==}
|
||||
|
||||
acorn-jsx@5.3.2:
|
||||
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
|
||||
peerDependencies:
|
||||
|
|
@ -1077,9 +1047,6 @@ packages:
|
|||
resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
|
||||
engines: {node: '>=4.0'}
|
||||
|
||||
estree-walker@2.0.2:
|
||||
resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
|
||||
|
||||
esutils@2.0.3:
|
||||
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
|
@ -1418,9 +1385,6 @@ packages:
|
|||
resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==}
|
||||
hasBin: true
|
||||
|
||||
magic-string@0.30.21:
|
||||
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
|
||||
|
||||
math-intrinsics@1.1.0:
|
||||
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
|
@ -1444,11 +1408,6 @@ packages:
|
|||
ms@2.1.3:
|
||||
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
||||
|
||||
nanoid@3.3.18:
|
||||
resolution: {integrity: sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==}
|
||||
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
||||
hasBin: true
|
||||
|
||||
natural-compare@1.4.0:
|
||||
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
|
||||
|
||||
|
|
@ -1518,10 +1477,6 @@ packages:
|
|||
resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
postcss@8.5.26:
|
||||
resolution: {integrity: sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==}
|
||||
engines: {node: ^10 || ^12 || >=14}
|
||||
|
||||
prelude-ls@1.2.1:
|
||||
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
|
||||
engines: {node: '>= 0.8.0'}
|
||||
|
|
@ -1625,10 +1580,6 @@ packages:
|
|||
resolution: {integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
source-map-js@1.2.1:
|
||||
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
source-map@0.6.1:
|
||||
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
|
@ -1727,14 +1678,6 @@ packages:
|
|||
uri-js@4.4.1:
|
||||
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
|
||||
|
||||
vue@3.5.41:
|
||||
resolution: {integrity: sha512-2laE0p+aK+/AOPG/XL/WepOs/GlK755LJ1XECi9kDUrz1FKNw8rb2Xzlw9JS1rqEV55nb0ttsKxVlTCcd+R5cg==}
|
||||
peerDependencies:
|
||||
typescript: '*'
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
|
||||
whatwg-mimetype@3.0.0:
|
||||
resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==}
|
||||
engines: {node: '>=12'}
|
||||
|
|
@ -2372,60 +2315,6 @@ snapshots:
|
|||
'@typescript-eslint/types': 8.67.0
|
||||
eslint-visitor-keys: 5.0.1
|
||||
|
||||
'@vue/compiler-core@3.5.41':
|
||||
dependencies:
|
||||
'@babel/parser': 7.29.8
|
||||
'@vue/shared': 3.5.41
|
||||
entities: 7.0.1
|
||||
estree-walker: 2.0.2
|
||||
source-map-js: 1.2.1
|
||||
|
||||
'@vue/compiler-dom@3.5.41':
|
||||
dependencies:
|
||||
'@vue/compiler-core': 3.5.41
|
||||
'@vue/shared': 3.5.41
|
||||
|
||||
'@vue/compiler-sfc@3.5.41':
|
||||
dependencies:
|
||||
'@babel/parser': 7.29.8
|
||||
'@vue/compiler-core': 3.5.41
|
||||
'@vue/compiler-dom': 3.5.41
|
||||
'@vue/compiler-ssr': 3.5.41
|
||||
'@vue/shared': 3.5.41
|
||||
estree-walker: 2.0.2
|
||||
magic-string: 0.30.21
|
||||
postcss: 8.5.26
|
||||
source-map-js: 1.2.1
|
||||
|
||||
'@vue/compiler-ssr@3.5.41':
|
||||
dependencies:
|
||||
'@vue/compiler-dom': 3.5.41
|
||||
'@vue/shared': 3.5.41
|
||||
|
||||
'@vue/reactivity@3.5.41':
|
||||
dependencies:
|
||||
'@vue/shared': 3.5.41
|
||||
|
||||
'@vue/runtime-core@3.5.41':
|
||||
dependencies:
|
||||
'@vue/reactivity': 3.5.41
|
||||
'@vue/shared': 3.5.41
|
||||
|
||||
'@vue/runtime-dom@3.5.41':
|
||||
dependencies:
|
||||
'@vue/reactivity': 3.5.41
|
||||
'@vue/runtime-core': 3.5.41
|
||||
'@vue/shared': 3.5.41
|
||||
csstype: 3.2.3
|
||||
|
||||
'@vue/server-renderer@3.5.41':
|
||||
dependencies:
|
||||
'@vue/compiler-ssr': 3.5.41
|
||||
'@vue/runtime-dom': 3.5.41
|
||||
'@vue/shared': 3.5.41
|
||||
|
||||
'@vue/shared@3.5.41': {}
|
||||
|
||||
acorn-jsx@5.3.2(acorn@8.18.0):
|
||||
dependencies:
|
||||
acorn: 8.18.0
|
||||
|
|
@ -2851,8 +2740,6 @@ snapshots:
|
|||
|
||||
estraverse@5.3.0: {}
|
||||
|
||||
estree-walker@2.0.2: {}
|
||||
|
||||
esutils@2.0.3: {}
|
||||
|
||||
fast-deep-equal@3.1.3: {}
|
||||
|
|
@ -3191,10 +3078,6 @@ snapshots:
|
|||
|
||||
lz-string@1.5.0: {}
|
||||
|
||||
magic-string@0.30.21:
|
||||
dependencies:
|
||||
'@jridgewell/sourcemap-codec': 1.5.5
|
||||
|
||||
math-intrinsics@1.1.0: {}
|
||||
|
||||
minimatch@10.2.6:
|
||||
|
|
@ -3213,8 +3096,6 @@ snapshots:
|
|||
|
||||
ms@2.1.3: {}
|
||||
|
||||
nanoid@3.3.18: {}
|
||||
|
||||
natural-compare@1.4.0: {}
|
||||
|
||||
neo-async@2.6.2: {}
|
||||
|
|
@ -3286,12 +3167,6 @@ snapshots:
|
|||
|
||||
possible-typed-array-names@1.1.0: {}
|
||||
|
||||
postcss@8.5.26:
|
||||
dependencies:
|
||||
nanoid: 3.3.18
|
||||
picocolors: 1.1.1
|
||||
source-map-js: 1.2.1
|
||||
|
||||
prelude-ls@1.2.1: {}
|
||||
|
||||
pretty-format@27.5.1:
|
||||
|
|
@ -3420,8 +3295,6 @@ snapshots:
|
|||
side-channel-map: 1.0.1
|
||||
side-channel-weakmap: 1.0.2
|
||||
|
||||
source-map-js@1.2.1: {}
|
||||
|
||||
source-map@0.6.1: {}
|
||||
|
||||
stop-iteration-iterator@1.1.0:
|
||||
|
|
@ -3548,16 +3421,6 @@ snapshots:
|
|||
dependencies:
|
||||
punycode: 2.3.1
|
||||
|
||||
vue@3.5.41(typescript@5.9.3):
|
||||
dependencies:
|
||||
'@vue/compiler-dom': 3.5.41
|
||||
'@vue/compiler-sfc': 3.5.41
|
||||
'@vue/runtime-dom': 3.5.41
|
||||
'@vue/server-renderer': 3.5.41
|
||||
'@vue/shared': 3.5.41
|
||||
optionalDependencies:
|
||||
typescript: 5.9.3
|
||||
|
||||
whatwg-mimetype@3.0.0: {}
|
||||
|
||||
which-boxed-primitive@1.1.1:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import * as rspack from '@rspack/core';
|
||||
|
||||
// Get the directory name of the current module
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
|
|
@ -82,14 +81,6 @@ const sharedStats = {
|
|||
modulesSpace: 20,
|
||||
};
|
||||
|
||||
function createVueDefinePlugin() {
|
||||
return new rspack.DefinePlugin({
|
||||
__VUE_OPTIONS_API__: JSON.stringify(true),
|
||||
__VUE_PROD_DEVTOOLS__: JSON.stringify(false),
|
||||
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: JSON.stringify(false),
|
||||
});
|
||||
}
|
||||
|
||||
function createReactModule(development, reactCompiler = false) {
|
||||
return {
|
||||
rules: [
|
||||
|
|
@ -167,9 +158,6 @@ export function createRspackConfigs(mode = 'production') {
|
|||
clean: true,
|
||||
},
|
||||
module: createReactModule(development, true),
|
||||
plugins: [
|
||||
createVueDefinePlugin(),
|
||||
],
|
||||
};
|
||||
|
||||
const mcpManagerConfig = {
|
||||
|
|
|
|||
|
|
@ -7,12 +7,13 @@ const OWNED_UI_ROOTS = [
|
|||
'src/scripts/tauri/setting',
|
||||
];
|
||||
|
||||
// Ratchet these limits down as each complete Vue root is migrated.
|
||||
const LIMITS = {
|
||||
runtimeTemplates: 0,
|
||||
vueImports: 0,
|
||||
vueRoots: 0,
|
||||
};
|
||||
const COMPILER_OWNED_ROOTS = [
|
||||
'src/scripts/extensions/agent-system/src',
|
||||
'src/scripts/extensions/mcp-manager/src',
|
||||
'src/scripts/tauri/setting/settings-app',
|
||||
'src/scripts/tauri/setting/dev-logs-app',
|
||||
'src/scripts/tauri/setting/sync-app',
|
||||
];
|
||||
|
||||
async function listFiles(directory) {
|
||||
const files = [];
|
||||
|
|
@ -31,26 +32,28 @@ async function listFiles(directory) {
|
|||
return files;
|
||||
}
|
||||
|
||||
const files = (await Promise.all(OWNED_UI_ROOTS.map(listFiles))).flat();
|
||||
const vueFiles = files.filter(file => path.extname(file) === '.vue');
|
||||
const sourceFiles = files.filter(file => ['.js', '.ts', '.tsx'].includes(path.extname(file)));
|
||||
const counts = {
|
||||
runtimeTemplates: 0,
|
||||
vueImports: 0,
|
||||
vueRoots: 0,
|
||||
};
|
||||
const ownedFiles = (await Promise.all(OWNED_UI_ROOTS.map(listFiles))).flat();
|
||||
const compilerOwnedFiles = (await Promise.all(COMPILER_OWNED_ROOTS.map(listFiles))).flat();
|
||||
const sourceFiles = ownedFiles.filter(file => /\.(?:js|jsx|ts|tsx)$/u.test(file));
|
||||
const errors = ownedFiles
|
||||
.filter(file => file.endsWith('.vue'))
|
||||
.map(file => `${file}: Vue SFCs are retired from first-party UI`);
|
||||
errors.push(
|
||||
...compilerOwnedFiles
|
||||
.filter(file => /(?:\.d\.ts|\.(?:js|jsx))$/u.test(file))
|
||||
.map(file => `${file}: compiler-owned first-party UI must use co-located TypeScript/TSX`),
|
||||
);
|
||||
|
||||
for (const file of sourceFiles) {
|
||||
const source = await fs.readFile(file, 'utf8');
|
||||
counts.runtimeTemplates += source.match(/\btemplate\s*:/gu)?.length ?? 0;
|
||||
counts.vueImports += source.match(/\bfrom\s+['"]vue(?:\/[^'"]*)?['"]|\bimport\s*\(\s*['"]vue(?:\/[^'"]*)?['"]\s*\)/gu)?.length ?? 0;
|
||||
counts.vueRoots += source.match(/\bcreateApp\s*\(/gu)?.length ?? 0;
|
||||
}
|
||||
|
||||
const errors = vueFiles.map(file => `${file}: first-party UI must not add Vue SFCs`);
|
||||
for (const [name, limit] of Object.entries(LIMITS)) {
|
||||
if (counts[name] > limit) {
|
||||
errors.push(`${name}: ${counts[name]} exceeds migration baseline ${limit}`);
|
||||
if (/\btemplate\s*:/u.test(source)) {
|
||||
errors.push(`${file}: runtime templates are retired from first-party UI`);
|
||||
}
|
||||
if (/\bfrom\s+['"]vue(?:\/[^'"]*)?['"]|\bimport\s*\(\s*['"]vue(?:\/[^'"]*)?['"]\s*\)/u.test(source)) {
|
||||
errors.push(`${file}: first-party UI must not import Vue`);
|
||||
}
|
||||
if (/\bcreateApp\s*\(/u.test(source)) {
|
||||
errors.push(`${file}: Vue application roots are retired from first-party UI`);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -58,5 +61,5 @@ if (errors.length > 0) {
|
|||
console.error(`[first-party-ui] FAILED\n${errors.map(error => `- ${error}`).join('\n')}`);
|
||||
process.exitCode = 1;
|
||||
} else {
|
||||
console.log(`[first-party-ui] clean (templates ${counts.runtimeTemplates}, Vue imports ${counts.vueImports}, roots ${counts.vueRoots})`);
|
||||
console.log('[first-party-ui] clean (React + strict TypeScript/TSX; raw Settings host adapters preserved)');
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue