feat(webui): Add UMD build format and CDN usage support

This commit is contained in:
yiliang114 2026-01-22 15:47:56 +08:00
parent 1f9311d3ca
commit 8d2d29a422
13 changed files with 796 additions and 189 deletions

View file

@ -50,7 +50,6 @@
.markdown-content p {
margin-top: 0;
/* margin-bottom: 1em; */
}
.markdown-content ul,

View file

@ -82,7 +82,8 @@ const parsePlanEntries = (textOutputs: string[]): PlanEntry[] => {
const entries: PlanEntry[] = [];
// Accept [ ], [x]/[X] and in-progress markers [-] or [*]
const todoRe = /^(?:\s*(?:[-*]|\d+[.)])\s*)?\[( |x|X|-|\*)\]\s+(.*)$/;
const todoRe =
/^(?:\s{0,10}(?:[-*]|\d{1,3}[.)])\s{0,10})?\[( |x|X|-|\*)\]\s+(.{0,500})$/;
for (const line of lines) {
const m = line.match(todoRe);
if (m) {

View file

@ -43,7 +43,9 @@ export const extractCommandOutput = (text: string): string => {
}
// Second try: Extract from structured text format
const outputMatch = text.match(/Output:[ \t]*(.+?)(?=\nError:|$)/i);
const outputMatch = text.match(
/Output:[ \t]{0,20}(.{0,1000}?)(?=\nError:|$)/i,
);
if (outputMatch && outputMatch[1]) {
const output = outputMatch[1].trim();
if (output && output !== '(none)' && output.length > 0) {

View file

@ -4,6 +4,10 @@
* SPDX-License-Identifier: Apache-2.0
*/
@tailwind base;
@tailwind components;
@tailwind utilities;
/**
* Default CSS variables for @qwen-code/webui
* These provide fallback values when running outside of VSCode.

View file

@ -1,178 +0,0 @@
/**
* @license
* Copyright 2025 Qwen Team
* SPDX-License-Identifier: Apache-2.0
*
* Isolated styles for VSCode webview environments to prevent conflicts
*/
/* Isolate all webui styles under a specific namespace to prevent global conflicts in webviews */
.qwen-webui-container {
/* Apply all CSS variables in the isolated namespace */
--app-primary: var(--app-primary, #3b82f6);
--app-primary-hover: var(--app-primary-hover, #2563eb);
--app-primary-foreground: var(--app-primary-foreground, #e4e4e7);
--app-secondary-foreground: var(--app-secondary-foreground, #a1a1aa);
--app-background: var(--app-background, #1e1e1e);
--app-primary-background: var(--app-primary-background, #1e1e1e);
--app-background-secondary: var(--app-background-secondary, #252526);
--app-secondary-background: var(--app-secondary-background, #252526);
--app-background-tertiary: var(--app-background-tertiary, #2d2d2d);
--app-foreground: var(--app-foreground, #e4e4e7);
--app-foreground-secondary: var(--app-foreground-secondary, #a1a1aa);
--app-foreground-muted: var(--app-foreground-muted, #71717a);
--app-border: var(--app-border, #3f3f46);
--app-border-focus: var(--app-border-focus, #3b82f6);
--app-primary-border-color: var(--app-primary-border-color, #3f3f46);
--app-success: var(--app-success, #10b981);
--app-warning: var(--app-warning, #f59e0b);
--app-error: var(--app-error, #ef4444);
--app-info: var(--app-info, #3b82f6);
--app-font-sans: var(--app-font-sans, system-ui, -apple-system, sans-serif);
--app-font-mono: var(--app-font-mono, ui-monospace, 'SF Mono', monospace);
--app-monospace-font-size: var(--app-monospace-font-size, 13px);
--app-link-foreground: var(--app-link-foreground, #007acc);
--app-link-active-foreground: var(--app-link-active-foreground, #005a9e);
--app-qwen-ivory: var(--app-qwen-ivory, #f5f5dc);
--app-radius-sm: var(--app-radius-sm, 0.25rem);
--app-radius-md: var(--app-radius-md, 0.375rem);
--app-radius-lg: var(--app-radius-lg, 0.5rem);
--qwen-corner-radius-small: var(--qwen-corner-radius-small, 6px);
--qwen-corner-radius-medium: var(--qwen-corner-radius-medium, 8px);
--app-spacing-xs: var(--app-spacing-xs, 0.25rem);
--app-spacing-sm: var(--app-spacing-sm, 0.5rem);
--app-spacing-md: var(--app-spacing-md, 1rem);
--app-spacing-medium: var(--app-spacing-medium, 8px);
--app-spacing-lg: var(--app-spacing-lg, 1.5rem);
--app-spacing-xl: var(--app-spacing-xl, 2rem);
--app-input-background: var(--app-input-background, #3c3c3c);
--app-input-secondary-background: var(--app-input-secondary-background, #2d2d2d);
--app-input-border: var(--app-input-border, #3f3f46);
--app-input-foreground: var(--app-input-foreground, #e4e4e7);
--app-input-placeholder-foreground: var(--app-input-placeholder-foreground, #71717a);
--app-ghost-button-hover-background: var(--app-ghost-button-hover-background, rgba(90, 93, 94, 0.31));
--app-button-background: var(--app-button-background, #3c3c3c);
--app-button-foreground: var(--app-button-foreground, #ffffff);
--app-transparent-inner-border: var(--app-transparent-inner-border, rgba(255, 255, 255, 0.1));
--app-header-background: var(--app-header-background, #252526);
--app-list-padding: var(--app-list-padding, 0px);
--app-list-item-padding: var(--app-list-item-padding, 4px 8px);
--app-list-border-color: var(--app-list-border-color, transparent);
--app-list-border-radius: var(--app-list-border-radius, 4px);
--app-list-hover-background: var(--app-list-hover-background, rgba(90, 93, 94, 0.31));
--app-list-active-background: var(--app-list-active-background, #094771);
--app-list-active-foreground: var(--app-list-active-foreground, #ffffff);
--app-list-gap: var(--app-list-gap, 2px);
--app-menu-background: var(--app-menu-background, #252526);
--app-menu-border: var(--app-menu-border, #454545);
--app-menu-foreground: var(--app-menu-foreground, #cccccc);
--app-menu-selection-background: var(--app-menu-selection-background, #094771);
--app-menu-selection-foreground: var(--app-menu-selection-foreground, #ffffff);
--app-tool-background: var(--app-tool-background, #1e1e1e);
--app-code-background: var(--app-code-background, #2d2d2d);
--app-warning-background: var(--app-warning-background, rgba(255, 204, 0, 0.1));
--app-warning-border: var(--app-warning-border, #ffcc00);
--app-warning-foreground: var(--app-warning-foreground, #ffcc00);
}
/* Reset potential conflicts with VSCode webview styles */
.qwen-webui-container *,
.qwen-webui-container *::before,
.qwen-webui-container *::after {
box-sizing: border-box;
}
/* Prevent styles from bleeding out of the container */
.qwen-webui-container {
all: inherit;
font: inherit;
line-height: inherit;
letter-spacing: inherit;
color: var(--app-foreground);
background: var(--app-background);
width: 100%;
height: 100%;
}
/* Isolated component styles */
.qwen-webui-container .code-block {
font-family: var(--app-font-mono);
font-size: var(--app-monospace-font-size, 13px);
background: var(--app-primary-background);
border: 1px solid var(--app-input-border);
border-radius: var(--app-radius-sm, 4px);
padding: var(--app-spacing-medium, 8px);
overflow-x: auto;
margin: 4px 0 0 0;
white-space: pre-wrap;
word-break: break-word;
max-height: 300px;
overflow-y: auto;
}
.qwen-webui-container .diff-display-container {
margin: 8px 0;
border: 1px solid var(--app-input-border);
border-radius: var(--app-radius-md, 6px);
overflow: hidden;
}
.qwen-webui-container .diff-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 8px 12px;
background: var(--app-input-secondary-background, var(--app-background-secondary));
border-bottom: 1px solid var(--app-input-border);
}
.qwen-webui-container .diff-file-path {
font-family: var(--app-font-mono);
font-size: 13px;
color: var(--app-primary-foreground);
}
.qwen-webui-container .open-diff-button {
display: flex;
align-items: center;
gap: 6px;
padding: 4px 8px;
background: transparent;
border: 1px solid var(--app-input-border);
border-radius: var(--app-radius-sm, 4px);
color: var(--app-primary-foreground);
cursor: pointer;
font-size: 12px;
transition: background-color 0.15s;
}
.qwen-webui-container .open-diff-button:hover {
background: var(--app-ghost-button-hover-background);
}
.qwen-webui-container .diff-label {
padding: 8px 12px;
background: var(--app-primary-background);
border-bottom: 1px solid var(--app-input-border);
font-size: 11px;
font-weight: 600;
color: var(--app-secondary-foreground);
text-transform: uppercase;
}