diff --git a/.github/workflows/release-vscode-companion.yml b/.github/workflows/release-vscode-companion.yml index ea02b01fb..101197529 100644 --- a/.github/workflows/release-vscode-companion.yml +++ b/.github/workflows/release-vscode-companion.yml @@ -223,7 +223,7 @@ jobs: npm --workspace=qwen-code-vscode-ide-companion run prepackage - name: 'Package VSIX (platform-specific)' - if: '${{ matrix.target != '''' }}' + if: "${{ matrix.target != '' }}" working-directory: 'packages/vscode-ide-companion' run: |- if [[ "${{ needs.prepare.outputs.is_preview }}" == "true" ]]; then @@ -236,7 +236,7 @@ jobs: shell: 'bash' - name: 'Package VSIX (universal)' - if: '${{ matrix.target == '''' }}' + if: "${{ matrix.target == '' }}" working-directory: 'packages/vscode-ide-companion' run: |- if [[ "${{ needs.prepare.outputs.is_preview }}" == "true" ]]; then @@ -251,7 +251,7 @@ jobs: - name: 'Upload VSIX Artifact' uses: 'actions/upload-artifact@v4' with: - name: 'vsix-${{ matrix.target || ''universal'' }}' + name: "vsix-${{ matrix.target || 'universal' }}" path: 'qwen-code-vscode-companion-${{ needs.prepare.outputs.release_version }}-*.vsix' if-no-files-found: 'error' @@ -292,7 +292,7 @@ jobs: npm install -g ovsx - name: 'Publish to Microsoft Marketplace' - if: '${{ needs.prepare.outputs.is_dry_run == ''false'' && needs.prepare.outputs.is_preview != ''true'' }}' + if: "${{ needs.prepare.outputs.is_dry_run == 'false' && needs.prepare.outputs.is_preview != 'true' }}" env: VSCE_PAT: '${{ secrets.VSCE_PAT }}' run: |- @@ -303,7 +303,7 @@ jobs: done - name: 'Publish to OpenVSX' - if: '${{ needs.prepare.outputs.is_dry_run == ''false'' }}' + if: "${{ needs.prepare.outputs.is_dry_run == 'false' }}" env: OVSX_TOKEN: '${{ secrets.OVSX_TOKEN }}' run: |- @@ -318,7 +318,7 @@ jobs: done - name: 'Upload all VSIXes as release artifacts (dry run)' - if: '${{ needs.prepare.outputs.is_dry_run == ''true'' }}' + if: "${{ needs.prepare.outputs.is_dry_run == 'true' }}" uses: 'actions/upload-artifact@v4' with: name: 'all-vsix-packages-${{ needs.prepare.outputs.release_version }}' diff --git a/integration-tests/concurrent-runner/render-chat-temp.html b/integration-tests/concurrent-runner/render-chat-temp.html index 5f33eaf69..bc6d01b61 100644 --- a/integration-tests/concurrent-runner/render-chat-temp.html +++ b/integration-tests/concurrent-runner/render-chat-temp.html @@ -1,277 +1,291 @@ - + + + + + Qwen Code Chat Export + + + - - - - Qwen Code Chat Export - - - + + - window.ReactJSXRuntime = jsxRuntime; - window['react/jsx-runtime'] = jsxRuntime; - window['react/jsx-dev-runtime'] = jsxRuntime; - + + - - + + - - + - - -
-
-
-

Qwen Code Export

-
-
-
- Session Id - - + /* Scrollbar styling */ + ::-webkit-scrollbar { + width: 10px; + height: 10px; + } + + ::-webkit-scrollbar-track { + background: var(--bg-primary); + } + + ::-webkit-scrollbar-thumb { + background: var(--bg-secondary); + border-radius: 5px; + border: 2px solid var(--bg-primary); + } + + ::-webkit-scrollbar-thumb:hover { + background: #52525b; + } + + /* Responsive adjustments */ + @media (max-width: 768px) { + .chat-container { + max-width: 100%; + padding: 20px 16px; + } + + .header { + padding: 12px 16px; + flex-direction: column; + align-items: flex-start; + gap: 12px; + } + + .header-left { + width: 100%; + justify-content: space-between; + } + + .meta { + width: 100%; + flex-direction: column; + gap: 6px; + } + } + + @media (max-width: 480px) { + .chat-container { + padding: 16px 12px; + } + } + + + + +
+
+
+

Qwen Code Export

-
- Export Time - - +
+
+ Session Id + - +
+
+ Export Time + - +
+ +
-
-
+ - - - - + // Render the ChatViewer component without Babel + const rootElementNoBabel = document.getElementById('chat-root-no-babel'); + // Create the ChatViewer element wrapped with PlatformProvider using React.createElement (no JSX) + const ChatAppNoBabel = React.createElement( + PlatformProvider, + { value: platformContext }, + React.createElement(ChatViewer, { + messages, + autoScroll: false, + theme: 'dark', + }), + ); + + ReactDOM.render(ChatAppNoBabel, rootElementNoBabel); + + diff --git a/packages/cli/src/acp-integration/session/Session.ts b/packages/cli/src/acp-integration/session/Session.ts index 77706030f..2b93a0256 100644 --- a/packages/cli/src/acp-integration/session/Session.ts +++ b/packages/cli/src/acp-integration/session/Session.ts @@ -53,7 +53,8 @@ import type { SetSessionModelRequest, SetSessionModelResponse, ToolCallContent, - AgentSideConnection} from '@agentclientprotocol/sdk'; + AgentSideConnection, +} from '@agentclientprotocol/sdk'; import type { LoadedSettings } from '../../config/settings.js'; import { z } from 'zod'; import { normalizePartList } from '../../utils/nonInteractiveHelpers.js'; diff --git a/packages/vscode-ide-companion/src/webview/styles/App.css b/packages/vscode-ide-companion/src/webview/styles/App.css index 6216d2b87..f3dc303db 100644 --- a/packages/vscode-ide-companion/src/webview/styles/App.css +++ b/packages/vscode-ide-companion/src/webview/styles/App.css @@ -95,7 +95,10 @@ /* Buttons - VSCode tokens */ --app-ghost-button-hover-background: var(--vscode-toolbar-hoverBackground); - --app-button-foreground: var(--vscode-button-foreground, var(--app-qwen-ivory)); + --app-button-foreground: var( + --vscode-button-foreground, + var(--app-qwen-ivory) + ); --app-button-background: var( --vscode-button-background, var(--app-qwen-clay-button-orange) diff --git a/packages/web-templates/src/export-html/src/components/TempFileModal.css b/packages/web-templates/src/export-html/src/components/TempFileModal.css index ba317104e..6c66c7804 100644 --- a/packages/web-templates/src/export-html/src/components/TempFileModal.css +++ b/packages/web-templates/src/export-html/src/components/TempFileModal.css @@ -48,7 +48,9 @@ padding: 4px 8px; border-radius: 6px; line-height: 1; - transition: background-color 0.15s, color 0.15s; + transition: + background-color 0.15s, + color 0.15s; } .modal-close:hover { diff --git a/packages/web-templates/src/insight/src/styles.css b/packages/web-templates/src/insight/src/styles.css index 8ef9af761..e65972d83 100644 --- a/packages/web-templates/src/insight/src/styles.css +++ b/packages/web-templates/src/insight/src/styles.css @@ -65,7 +65,7 @@ :before, :after { - --tw-content: ""; + --tw-content: ''; } html, @@ -75,7 +75,9 @@ html, font-feature-settings: normal; font-variation-settings: normal; -webkit-tap-highlight-color: transparent; - font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + font-family: + ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', + 'Segoe UI Symbol', 'Noto Color Emoji'; line-height: 1.5; } @@ -85,7 +87,9 @@ body { background-image: linear-gradient(to bottom right, var(--tw-gradient-stops)); --tw-gradient-from: #f8fafc var(--tw-gradient-from-position); --tw-gradient-to: #f1f5f9 var(--tw-gradient-to-position); - --tw-gradient-stops: var(--tw-gradient-from), #fff var(--tw-gradient-via-position), var(--tw-gradient-to); + --tw-gradient-stops: + var(--tw-gradient-from), #fff var(--tw-gradient-via-position), + var(--tw-gradient-to); --tw-text-opacity: 1; min-height: 100vh; color: rgb(15 23 42 / var(--tw-text-opacity, 1)); @@ -100,9 +104,15 @@ body { border-color: rgb(226 232 240 / var(--tw-border-opacity, 1)); --tw-shadow: 0 10px 40px #0f172a14; --tw-shadow-colored: 0 10px 40px var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + box-shadow: + var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), + var(--tw-shadow); --tw-backdrop-blur: blur(8px); - backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); + backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) + var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) + var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) + var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) + var(--tw-backdrop-sepia); background-color: #ffffff99; border-radius: 1rem; } @@ -225,25 +235,25 @@ body { gap: 1rem; } -.space-y-3> :not([hidden])~ :not([hidden]) { +.space-y-3 > :not([hidden]) ~ :not([hidden]) { --tw-space-y-reverse: 0; margin-top: calc(0.75rem * calc(1 - var(--tw-space-y-reverse))); margin-bottom: calc(0.75rem * var(--tw-space-y-reverse)); } -.space-y-4> :not([hidden])~ :not([hidden]) { +.space-y-4 > :not([hidden]) ~ :not([hidden]) { --tw-space-y-reverse: 0; margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse))); margin-bottom: calc(1rem * var(--tw-space-y-reverse)); } -.divide-y> :not([hidden])~ :not([hidden]) { +.divide-y > :not([hidden]) ~ :not([hidden]) { --tw-divide-y-reverse: 0; border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse))); border-bottom-width: calc(1px * var(--tw-divide-y-reverse)); } -.divide-slate-200> :not([hidden])~ :not([hidden]) { +.divide-slate-200 > :not([hidden]) ~ :not([hidden]) { --tw-divide-opacity: 1; border-color: rgb(226 232 240 / var(--tw-divide-opacity, 1)); } @@ -305,7 +315,9 @@ body { .via-white { --tw-gradient-to: #ffffff00 var(--tw-gradient-to-position); - --tw-gradient-stops: var(--tw-gradient-from), #ffffff var(--tw-gradient-via-position), var(--tw-gradient-to); + --tw-gradient-stops: + var(--tw-gradient-from), #ffffff var(--tw-gradient-via-position), + var(--tw-gradient-to); } .to-slate-100 { @@ -494,13 +506,17 @@ body { .shadow-inner { --tw-shadow: inset 0 2px 4px 0 #0000000d; --tw-shadow-colored: inset 0 2px 4px 0 var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + box-shadow: + var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), + var(--tw-shadow); } .shadow-soft { --tw-shadow: 0 10px 40px #0f172a14; --tw-shadow-colored: 0 10px 40px var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + box-shadow: + var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), + var(--tw-shadow); } .shadow-slate-100 { @@ -509,20 +525,28 @@ body { } .transition { - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-property: + color, background-color, border-color, text-decoration-color, fill, stroke, + opacity, box-shadow, transform, filter, backdrop-filter; transition-duration: 0.15s; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); } .hover\:-translate-y-\[1px\]:hover { --tw-translate-y: -1px; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) + rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) + scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } .hover\:shadow-lg:hover { --tw-shadow: 0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a; - --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + --tw-shadow-colored: + 0 10px 15px -3px var(--tw-shadow-color), + 0 4px 6px -4px var(--tw-shadow-color); + box-shadow: + var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), + var(--tw-shadow); } .focus-visible\:outline:focus-visible { @@ -543,12 +567,16 @@ body { .active\:translate-y-\[1px\]:active { --tw-translate-y: 1px; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) + rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) + scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } .group:hover .group-hover\:translate-x-0\.5 { --tw-translate-x: 0.125rem; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) + rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) + scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } @media (min-width: 768px) { @@ -1259,4 +1287,4 @@ body { .header-title { font-size: 1.5rem; } -} \ No newline at end of file +} diff --git a/packages/webui/examples/cdn-usage-demo.html b/packages/webui/examples/cdn-usage-demo.html index c013e9078..2919614af 100644 --- a/packages/webui/examples/cdn-usage-demo.html +++ b/packages/webui/examples/cdn-usage-demo.html @@ -1,99 +1,117 @@ - + + + + + @qwen-code/webui CDN Usage Example + + + - - - - @qwen-code/webui CDN Usage Example - - - + + - window.ReactJSXRuntime = jsxRuntime; - window['react/jsx-runtime'] = jsxRuntime; - window['react/jsx-dev-runtime'] = jsxRuntime; - + + - - + + - - - - - - - -
-

@qwen-code/webui CDN Usage Example

-

ChatViewer Component Demo

-
-
- - - + theme: 'light', + }), + ); + ReactDOM.render(ChatAppNoBabel, rootElementNoBabel); + + diff --git a/packages/webui/examples/complex-chat-demo.html b/packages/webui/examples/complex-chat-demo.html index c05be1e1b..22adbc3dd 100644 --- a/packages/webui/examples/complex-chat-demo.html +++ b/packages/webui/examples/complex-chat-demo.html @@ -1,99 +1,112 @@ - + + + + + @qwen-code/webui Complex Chat Demo + + + + + - - - - @qwen-code/webui Complex Chat Demo - - - - - + + - - + + - - + + - window.ReactJSXRuntime = jsxRuntime; - window['react/jsx-runtime'] = jsxRuntime; - window['react/jsx-dev-runtime'] = jsxRuntime; - + + - .chat-container { - height: 700px; - border: 1px solid #ddd; - border-radius: 4px; - overflow: hidden; - } - - + +
+

@qwen-code/webui Complex Chat Demo

+

Real conversation example with tool calls

+
- -
-

@qwen-code/webui Complex Chat Demo

-

Real conversation example with tool calls

-
+

Alternative: With Full Tailwind Support

+

+ For full Tailwind utility class support (like gap-1.5, button classes, + etc.), also include: +

+
<script src="https://cdn.tailwindcss.com"></script>
+
-

Alternative: With Full Tailwind Support

-

For full Tailwind utility class support (like gap-1.5, button classes, etc.), also include:

-
<script src="https://cdn.tailwindcss.com"></script>
-
- - - + // Create the ChatViewer element wrapped with PlatformProvider with complex data + const ChatApp = React.createElement( + PlatformProvider, + { value: platformContext }, + React.createElement(ChatViewer, { + messages: combinedMessages, + autoScroll: true, + theme: 'light', + emptyMessage: 'Loading conversation...', + }), + ); + ReactDOM.render(ChatApp, rootElement); + + diff --git a/packages/webui/src/components/ChatViewer/ChatViewer.css b/packages/webui/src/components/ChatViewer/ChatViewer.css index 3d8144caf..94b8dca78 100644 --- a/packages/webui/src/components/ChatViewer/ChatViewer.css +++ b/packages/webui/src/components/ChatViewer/ChatViewer.css @@ -15,9 +15,22 @@ flex-direction: column; width: 100%; height: 100%; - background-color: var(--app-background, var(--app-primary-background, #1e1e1e)); + background-color: var( + --app-background, + var(--app-primary-background, #1e1e1e) + ); color: var(--app-primary-foreground, #cccccc); - font-family: var(--vscode-chat-font-family, var(--vscode-font-family, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif)); + font-family: var( + --vscode-chat-font-family, + var( + --vscode-font-family, + -apple-system, + BlinkMacSystemFont, + 'Segoe UI', + Roboto, + sans-serif + ) + ); font-size: var(--vscode-chat-font-size, 13px); overflow: hidden; } @@ -58,21 +71,25 @@ /* Light theme scrollbar styling */ @media (prefers-color-scheme: light) { - .chat-viewer-container.auto-theme .chat-viewer-messages::-webkit-scrollbar-thumb { + .chat-viewer-container.auto-theme + .chat-viewer-messages::-webkit-scrollbar-thumb { background: rgba(0, 0, 0, 0.2); } - - .chat-viewer-container.auto-theme .chat-viewer-messages::-webkit-scrollbar-thumb:hover { + + .chat-viewer-container.auto-theme + .chat-viewer-messages::-webkit-scrollbar-thumb:hover { background: rgba(0, 0, 0, 0.3); } } /* Force light theme scrollbar */ -.chat-viewer-container.light-theme .chat-viewer-messages::-webkit-scrollbar-thumb { +.chat-viewer-container.light-theme + .chat-viewer-messages::-webkit-scrollbar-thumb { background: rgba(0, 0, 0, 0.2); } -.chat-viewer-container.light-theme .chat-viewer-messages::-webkit-scrollbar-thumb:hover { +.chat-viewer-container.light-theme + .chat-viewer-messages::-webkit-scrollbar-thumb:hover { background: rgba(0, 0, 0, 0.3); } diff --git a/packages/webui/src/components/messages/Assistant/AssistantMessage.css b/packages/webui/src/components/messages/Assistant/AssistantMessage.css index a9a1369fd..24ebbe26f 100644 --- a/packages/webui/src/components/messages/Assistant/AssistantMessage.css +++ b/packages/webui/src/components/messages/Assistant/AssistantMessage.css @@ -63,8 +63,13 @@ } @keyframes assistantPulse { - 0%, 100% { opacity: 1; } - 50% { opacity: 0.5; } + 0%, + 100% { + opacity: 1; + } + 50% { + opacity: 0.5; + } } /* Timeline connector line - full height by default */ diff --git a/packages/webui/src/styles/components.css b/packages/webui/src/styles/components.css index e873e7d9e..7ef3cd237 100644 --- a/packages/webui/src/styles/components.css +++ b/packages/webui/src/styles/components.css @@ -180,7 +180,10 @@ align-items: center; justify-content: space-between; padding: 8px 12px; - background: var(--app-input-secondary-background, var(--app-background-secondary)); + background: var( + --app-input-secondary-background, + var(--app-background-secondary) + ); border-bottom: 1px solid var(--app-input-border); } @@ -393,7 +396,10 @@ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); transition: border-color 0.2s; z-index: 1; - background: var(--app-input-secondary-background, var(--app-background-secondary)); + background: var( + --app-input-secondary-background, + var(--app-background-secondary) + ); color: var(--app-input-foreground); } @@ -424,7 +430,7 @@ } .composer-input:empty::before, -.composer-input[data-empty="true"]::before { +.composer-input[data-empty='true']::before { content: attr(data-placeholder); color: var(--app-input-placeholder-foreground); pointer-events: none; @@ -440,7 +446,7 @@ } .composer-input:disabled, -.composer-input[contenteditable="false"] { +.composer-input[contenteditable='false'] { color: #999; cursor: not-allowed; } diff --git a/packages/webui/src/styles/timeline.css b/packages/webui/src/styles/timeline.css index b69aeb815..d437938df 100644 --- a/packages/webui/src/styles/timeline.css +++ b/packages/webui/src/styles/timeline.css @@ -46,7 +46,9 @@ top: var(--timeline-center-offset, 13px); } -.qwen-message.message-item:not(.user-message-container):has(+ .user-message-container)::after, +.qwen-message.message-item:not(.user-message-container):has( + + .user-message-container + )::after, .qwen-message.message-item:not(.user-message-container):has( + :not(.qwen-message.message-item) )::after,