mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-19 09:33:53 +00:00
build(vscode-ide-companion): 添加 SCSS 支持
- 在 esbuild.js 中添加 SCSS 文件处理逻辑 - 在 package.json 中添加 sass 依赖 - 新增代码使用 sass 编译 SCSS 文件,并将其注入到页面中
This commit is contained in:
407
package-lock.json
generated
407
package-lock.json
generated
@@ -2642,6 +2642,354 @@
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz",
|
||||
"integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"detect-libc": "^1.0.3",
|
||||
"is-glob": "^4.0.3",
|
||||
"micromatch": "^4.0.5",
|
||||
"node-addon-api": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@parcel/watcher-android-arm64": "2.5.1",
|
||||
"@parcel/watcher-darwin-arm64": "2.5.1",
|
||||
"@parcel/watcher-darwin-x64": "2.5.1",
|
||||
"@parcel/watcher-freebsd-x64": "2.5.1",
|
||||
"@parcel/watcher-linux-arm-glibc": "2.5.1",
|
||||
"@parcel/watcher-linux-arm-musl": "2.5.1",
|
||||
"@parcel/watcher-linux-arm64-glibc": "2.5.1",
|
||||
"@parcel/watcher-linux-arm64-musl": "2.5.1",
|
||||
"@parcel/watcher-linux-x64-glibc": "2.5.1",
|
||||
"@parcel/watcher-linux-x64-musl": "2.5.1",
|
||||
"@parcel/watcher-win32-arm64": "2.5.1",
|
||||
"@parcel/watcher-win32-ia32": "2.5.1",
|
||||
"@parcel/watcher-win32-x64": "2.5.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-android-arm64": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz",
|
||||
"integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-darwin-arm64": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz",
|
||||
"integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-darwin-x64": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz",
|
||||
"integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-freebsd-x64": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz",
|
||||
"integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-linux-arm-glibc": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz",
|
||||
"integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-linux-arm-musl": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz",
|
||||
"integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-linux-arm64-glibc": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz",
|
||||
"integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-linux-arm64-musl": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz",
|
||||
"integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-linux-x64-glibc": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz",
|
||||
"integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-linux-x64-musl": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz",
|
||||
"integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-win32-arm64": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz",
|
||||
"integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-win32-ia32": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz",
|
||||
"integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-win32-x64": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz",
|
||||
"integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher/node_modules/detect-libc": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
|
||||
"integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"detect-libc": "bin/detect-libc.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher/node_modules/node-addon-api": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
|
||||
"integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@pkgjs/parseargs": {
|
||||
"version": "0.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
|
||||
@@ -5824,6 +6172,22 @@
|
||||
"entities": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/chokidar": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
|
||||
"integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"readdirp": "^4.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14.16.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/chownr": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz",
|
||||
@@ -8971,6 +9335,13 @@
|
||||
"node": ">= 4"
|
||||
}
|
||||
},
|
||||
"node_modules/immutable": {
|
||||
"version": "5.1.4",
|
||||
"resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.4.tgz",
|
||||
"integrity": "sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/import-fresh": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
|
||||
@@ -12884,6 +13255,20 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/readdirp": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
|
||||
"integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 14.18.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "individual",
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/reflect.getprototypeof": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
|
||||
@@ -13282,6 +13667,27 @@
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/sass": {
|
||||
"version": "1.94.1",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.94.1.tgz",
|
||||
"integrity": "sha512-/YVm5FRQaRlr3oNh2LLFYne1PdPlRZGyKnHh1sLleOqLcohTR4eUUvBjBIqkl1fEXd1MGOHgzJGJh+LgTtV4KQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"chokidar": "^4.0.0",
|
||||
"immutable": "^5.0.2",
|
||||
"source-map-js": ">=0.6.2 <2.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"sass": "sass.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@parcel/watcher": "^2.4.1"
|
||||
}
|
||||
},
|
||||
"node_modules/sax": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz",
|
||||
@@ -16320,6 +16726,7 @@
|
||||
"esbuild": "^0.25.3",
|
||||
"eslint": "^9.25.1",
|
||||
"npm-run-all2": "^8.0.2",
|
||||
"sass": "^1.94.1",
|
||||
"typescript": "^5.8.3",
|
||||
"vitest": "^3.2.4"
|
||||
},
|
||||
|
||||
@@ -37,6 +37,7 @@ const esbuildProblemMatcherPlugin = {
|
||||
const cssInjectPlugin = {
|
||||
name: 'css-inject',
|
||||
setup(build) {
|
||||
// Handle CSS files
|
||||
build.onLoad({ filter: /\.css$/ }, async (args) => {
|
||||
const fs = await import('fs');
|
||||
const css = await fs.promises.readFile(args.path, 'utf8');
|
||||
@@ -49,6 +50,23 @@ const cssInjectPlugin = {
|
||||
loader: 'js',
|
||||
};
|
||||
});
|
||||
|
||||
// Handle SCSS files
|
||||
build.onLoad({ filter: /\.scss$/ }, async (args) => {
|
||||
const sass = await import('sass');
|
||||
const result = sass.compile(args.path, {
|
||||
loadPaths: [args.path.substring(0, args.path.lastIndexOf('/'))],
|
||||
});
|
||||
const css = result.css;
|
||||
return {
|
||||
contents: `
|
||||
const style = document.createElement('style');
|
||||
style.textContent = ${JSON.stringify(css)};
|
||||
document.head.appendChild(style);
|
||||
`,
|
||||
loader: 'js',
|
||||
};
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -178,6 +178,7 @@
|
||||
"esbuild": "^0.25.3",
|
||||
"eslint": "^9.25.1",
|
||||
"npm-run-all2": "^8.0.2",
|
||||
"sass": "^1.94.1",
|
||||
"typescript": "^5.8.3",
|
||||
"vitest": "^3.2.4"
|
||||
},
|
||||
|
||||
@@ -298,6 +298,22 @@ button {
|
||||
padding: var(--app-spacing-medium);
|
||||
}
|
||||
|
||||
.thinking-message {
|
||||
background-color: var(--app-list-hover-background, rgba(100, 100, 255, 0.1));
|
||||
opacity: 0.8;
|
||||
font-style: italic;
|
||||
position: relative;
|
||||
padding-left: 24px;
|
||||
}
|
||||
|
||||
.thinking-message::before {
|
||||
content: "💭";
|
||||
position: absolute;
|
||||
left: 6px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.thinking-label {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
@@ -314,6 +330,70 @@ button {
|
||||
color: rgba(200, 200, 255, 0.9);
|
||||
}
|
||||
|
||||
/* Waiting message styles - similar to Claude Code thinking state */
|
||||
.message.waiting-message {
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
.waiting-message .message-content {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
padding: 8px 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
/* Typing indicator for loading messages */
|
||||
.typing-indicator {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
margin-right: 0;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.typing-dot, .thinking-dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
background-color: var(--app-secondary-foreground);
|
||||
border-radius: 50%;
|
||||
margin-right: 0;
|
||||
opacity: 0.6;
|
||||
animation: typingPulse 1.4s infinite ease-in-out;
|
||||
}
|
||||
|
||||
.typing-dot:nth-child(1),
|
||||
.thinking-dot:nth-child(1) {
|
||||
animation-delay: 0s;
|
||||
}
|
||||
|
||||
.typing-dot:nth-child(2),
|
||||
.thinking-dot:nth-child(2) {
|
||||
animation-delay: 0.2s;
|
||||
}
|
||||
|
||||
.typing-dot:nth-child(3),
|
||||
.thinking-dot:nth-child(3) {
|
||||
animation-delay: 0.4s;
|
||||
}
|
||||
|
||||
@keyframes typingPulse {
|
||||
0%, 60%, 100% {
|
||||
transform: scale(0.7);
|
||||
opacity: 0.6;
|
||||
}
|
||||
30% {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.loading-text {
|
||||
opacity: 0.7;
|
||||
font-style: italic;
|
||||
color: var(--app-secondary-foreground);
|
||||
}
|
||||
|
||||
/* ===========================
|
||||
Scrollbar Styling
|
||||
=========================== */
|
||||
@@ -190,13 +190,15 @@ export const App: React.FC = () => {
|
||||
const [messages, setMessages] = useState<TextMessage[]>([]);
|
||||
const [inputText, setInputText] = useState('');
|
||||
const [isStreaming, setIsStreaming] = useState(false);
|
||||
const [_isWaitingForResponse, setIsWaitingForResponse] = useState(false);
|
||||
const [_loadingMessage, setLoadingMessage] = useState('');
|
||||
const [isWaitingForResponse, setIsWaitingForResponse] = useState(false);
|
||||
const [loadingMessage, setLoadingMessage] = useState('');
|
||||
const [currentStreamContent, setCurrentStreamContent] = useState('');
|
||||
const [qwenSessions, setQwenSessions] = useState<
|
||||
Array<Record<string, unknown>>
|
||||
>([]);
|
||||
const [currentSessionId, setCurrentSessionId] = useState<string | null>(null);
|
||||
const [currentSessionTitle, setCurrentSessionTitle] =
|
||||
useState<string>('Past Conversations');
|
||||
const [showSessionSelector, setShowSessionSelector] = useState(false);
|
||||
const [sessionSearchQuery, setSessionSearchQuery] = useState('');
|
||||
const [permissionRequest, setPermissionRequest] = useState<{
|
||||
@@ -336,6 +338,18 @@ export const App: React.FC = () => {
|
||||
break;
|
||||
}
|
||||
|
||||
case 'thoughtChunk': {
|
||||
const chunkData = message.data;
|
||||
// Handle thought chunks for AI thinking display
|
||||
const thinkingMessage: TextMessage = {
|
||||
role: 'thinking',
|
||||
content: chunkData.content || chunkData.chunk || '',
|
||||
timestamp: Date.now(),
|
||||
};
|
||||
setMessages((prev) => [...prev, thinkingMessage]);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'streamEnd':
|
||||
// Finalize the streamed message
|
||||
if (currentStreamContentRef.current) {
|
||||
@@ -347,12 +361,14 @@ export const App: React.FC = () => {
|
||||
setMessages((prev) => [...prev, assistantMessage]);
|
||||
}
|
||||
setIsStreaming(false);
|
||||
setIsWaitingForResponse(false); // Clear waiting state
|
||||
setCurrentStreamContent('');
|
||||
currentStreamContentRef.current = '';
|
||||
break;
|
||||
|
||||
case 'error':
|
||||
setIsStreaming(false);
|
||||
setIsWaitingForResponse(false);
|
||||
break;
|
||||
|
||||
case 'permissionRequest':
|
||||
@@ -371,10 +387,30 @@ export const App: React.FC = () => {
|
||||
setQwenSessions(sessions);
|
||||
// If no current session is selected and there are sessions, select the first one
|
||||
if (!currentSessionId && sessions.length > 0) {
|
||||
const firstSession = sessions[0];
|
||||
const firstSessionId =
|
||||
(sessions[0].id as string) || (sessions[0].sessionId as string);
|
||||
(firstSession.id as string) || (firstSession.sessionId as string);
|
||||
const firstSessionTitle =
|
||||
(firstSession.title as string) ||
|
||||
(firstSession.name as string) ||
|
||||
'Past Conversations';
|
||||
if (firstSessionId) {
|
||||
setCurrentSessionId(firstSessionId);
|
||||
setCurrentSessionTitle(firstSessionTitle);
|
||||
}
|
||||
} else if (currentSessionId && sessions.length > 0) {
|
||||
// Update title for the current session if it exists in the list
|
||||
const currentSession = sessions.find(
|
||||
(s: Record<string, unknown>) =>
|
||||
(s.id as string) === currentSessionId ||
|
||||
(s.sessionId as string) === currentSessionId,
|
||||
);
|
||||
if (currentSession) {
|
||||
const title =
|
||||
(currentSession.title as string) ||
|
||||
(currentSession.name as string) ||
|
||||
'Past Conversations';
|
||||
setCurrentSessionTitle(title);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -391,6 +427,14 @@ export const App: React.FC = () => {
|
||||
message.data.sessionId,
|
||||
);
|
||||
}
|
||||
// Update current session title
|
||||
if (message.data.title || message.data.name) {
|
||||
const title =
|
||||
(message.data.title as string) ||
|
||||
(message.data.name as string) ||
|
||||
'Past Conversations';
|
||||
setCurrentSessionTitle(title);
|
||||
}
|
||||
// Load messages from the session
|
||||
if (message.data.messages) {
|
||||
console.log(
|
||||
@@ -463,6 +507,7 @@ export const App: React.FC = () => {
|
||||
vscode.postMessage({ type: 'newQwenSession', data: {} });
|
||||
setShowSessionSelector(false);
|
||||
setCurrentSessionId(null);
|
||||
setCurrentSessionTitle('Past Conversations'); // Reset title to default
|
||||
// Clear messages in UI
|
||||
setMessages([]);
|
||||
setCurrentStreamContent('');
|
||||
@@ -694,7 +739,7 @@ export const App: React.FC = () => {
|
||||
title="Past conversations"
|
||||
>
|
||||
<span className="button-content">
|
||||
<span className="button-text">Past Conversations</span>
|
||||
<span className="button-text">{currentSessionTitle}</span>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20"
|
||||
@@ -734,14 +779,31 @@ export const App: React.FC = () => {
|
||||
<EmptyState />
|
||||
) : (
|
||||
<>
|
||||
{messages.map((msg, index) => (
|
||||
<div key={index} className={`message ${msg.role}`}>
|
||||
<div className="message-content">{msg.content}</div>
|
||||
{messages.map((msg, index) => {
|
||||
// Special styling for thinking messages (Claude Code style)
|
||||
const messageClass =
|
||||
msg.role === 'thinking'
|
||||
? 'message assistant thinking-message'
|
||||
: `message ${msg.role}`;
|
||||
|
||||
return (
|
||||
<div key={index} className={messageClass}>
|
||||
<div className="message-content">
|
||||
{msg.role === 'thinking' && (
|
||||
<span className="thinking-indicator">
|
||||
<span className="thinking-dot"></span>
|
||||
<span className="thinking-dot"></span>
|
||||
<span className="thinking-dot"></span>
|
||||
</span>
|
||||
)}
|
||||
{msg.content}
|
||||
</div>
|
||||
<div className="message-timestamp">
|
||||
{new Date(msg.timestamp).toLocaleTimeString()}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
);
|
||||
})}
|
||||
|
||||
{/* Tool Calls */}
|
||||
{Array.from(toolCalls.values()).map((toolCall) => (
|
||||
@@ -757,6 +819,20 @@ export const App: React.FC = () => {
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Loading/Waiting Message - in message list */}
|
||||
{isWaitingForResponse && loadingMessage && (
|
||||
<div className="message assistant waiting-message">
|
||||
<div className="message-content">
|
||||
<span className="typing-indicator">
|
||||
<span className="typing-dot"></span>
|
||||
<span className="typing-dot"></span>
|
||||
<span className="typing-dot"></span>
|
||||
</span>
|
||||
<span className="loading-text">{loadingMessage}</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{isStreaming && currentStreamContent && (
|
||||
<div className="message assistant streaming">
|
||||
<div className="message-content">{currentStreamContent}</div>
|
||||
@@ -830,7 +906,7 @@ export const App: React.FC = () => {
|
||||
role="textbox"
|
||||
aria-label="Message input"
|
||||
aria-multiline="true"
|
||||
data-placeholder="Ask qwen to edit…"
|
||||
data-placeholder="Ask Qwen Code …"
|
||||
onInput={(e) => {
|
||||
const target = e.target as HTMLDivElement;
|
||||
setInputText(target.textContent || '');
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
import ReactDOM from 'react-dom/client';
|
||||
import { App } from './App.js';
|
||||
import './App.css';
|
||||
import './App.scss';
|
||||
import './ClaudeCodeStyles.css';
|
||||
|
||||
const container = document.getElementById('root');
|
||||
|
||||
Reference in New Issue
Block a user