From af76450deef6fe76da8895372879fb4e27d9ed64 Mon Sep 17 00:00:00 2001 From: yiliang114 <1204183885@qq.com> Date: Thu, 15 Jan 2026 14:32:21 +0800 Subject: [PATCH] feat(webui): Infrastructure Setup (Prerequisites) --- .gitignore | 3 + eslint.config.js | 522 ++-- package-lock.json | 2664 ++++++++++++++++- packages/vscode-ide-companion/package.json | 2 +- packages/webui/.storybook/main.ts | 25 + packages/webui/.storybook/preview.css | 11 + packages/webui/.storybook/preview.ts | 15 + packages/webui/WEBUI_MIGRATION_PLAN_EN.md | 428 +++ packages/webui/WEBUI_MIGRATION_PLAN_ZH.md | 428 +++ packages/webui/package.json | 54 +- packages/webui/postcss.config.cjs | 13 + packages/webui/rollup.config.js | 47 - .../src/components/ui/Button.stories.tsx | 83 + .../src/components/ui/Tooltip.stories.tsx | 68 + .../webui/src/context/PlatformContext.tsx | 89 + packages/webui/src/index.ts | 19 + packages/webui/src/styles/variables.css | 52 + packages/webui/src/types/chat.ts | 28 + packages/webui/src/types/toolCall.ts | 48 + packages/webui/tailwind.config.cjs | 11 + packages/webui/tailwind.preset.cjs | 71 + packages/webui/tsconfig.json | 7 +- packages/webui/vite.config.ts | 53 + 23 files changed, 4367 insertions(+), 374 deletions(-) create mode 100644 packages/webui/.storybook/main.ts create mode 100644 packages/webui/.storybook/preview.css create mode 100644 packages/webui/.storybook/preview.ts create mode 100644 packages/webui/WEBUI_MIGRATION_PLAN_EN.md create mode 100644 packages/webui/WEBUI_MIGRATION_PLAN_ZH.md create mode 100644 packages/webui/postcss.config.cjs delete mode 100644 packages/webui/rollup.config.js create mode 100644 packages/webui/src/components/ui/Button.stories.tsx create mode 100644 packages/webui/src/components/ui/Tooltip.stories.tsx create mode 100644 packages/webui/src/context/PlatformContext.tsx create mode 100644 packages/webui/src/styles/variables.css create mode 100644 packages/webui/src/types/chat.ts create mode 100644 packages/webui/src/types/toolCall.ts create mode 100644 packages/webui/tailwind.config.cjs create mode 100644 packages/webui/tailwind.preset.cjs create mode 100644 packages/webui/vite.config.ts diff --git a/.gitignore b/.gitignore index 705216c80..8f088bc64 100644 --- a/.gitignore +++ b/.gitignore @@ -63,3 +63,6 @@ patch_output.log docs-site/.next # content is a symlink to ../docs docs-site/content + +*storybook.log +storybook-static diff --git a/eslint.config.js b/eslint.config.js index 78ff26c88..86fb9a4e3 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,3 +1,6 @@ +// For more info, see https://github.com/storybookjs/eslint-plugin-storybook#configuration-flat-config-format +import storybook from "eslint-plugin-storybook"; + /** * @license * Copyright 2025 Google LLC @@ -13,277 +16,260 @@ import importPlugin from 'eslint-plugin-import'; import vitest from '@vitest/eslint-plugin'; import globals from 'globals'; -export default tseslint.config( - { - // Global ignores - ignores: [ - 'node_modules/*', - 'packages/**/dist/**', - 'bundle/**', - 'package/bundle/**', - '.integration-tests/**', - 'packages/**/.integration-test/**', - 'dist/**', - 'docs-site/.next/**', - 'docs-site/out/**', +export default tseslint.config({ + // Global ignores + ignores: [ + 'node_modules/*', + 'packages/**/dist/**', + 'bundle/**', + 'package/bundle/**', + '.integration-tests/**', + 'packages/**/.integration-test/**', + 'dist/**', + 'docs-site/.next/**', + 'docs-site/out/**', + ], +}, eslint.configs.recommended, ...tseslint.configs.recommended, reactHooks.configs['recommended-latest'], reactPlugin.configs.flat.recommended, // Add this if you are using React 17+ +reactPlugin.configs.flat['jsx-runtime'], { + // Settings for eslint-plugin-react + settings: { + react: { + version: 'detect', + }, + }, +}, { + // Import specific config + files: ['packages/cli/src/**/*.{ts,tsx}'], // Target only TS/TSX in the cli package + plugins: { + import: importPlugin, + }, + settings: { + 'import/resolver': { + node: true, + }, + }, + rules: { + ...importPlugin.configs.recommended.rules, + ...importPlugin.configs.typescript.rules, + 'import/no-default-export': 'warn', + 'import/no-unresolved': 'off', // Disable for now, can be noisy with monorepos/paths + }, +}, { + // General overrides and rules for the project (TS/TSX files) + files: ['packages/*/src/**/*.{ts,tsx}'], // Target only TS/TSX in the cli package + plugins: { + import: importPlugin, + }, + settings: { + 'import/resolver': { + node: true, + }, + }, + languageOptions: { + globals: { + ...globals.node, + ...globals.es2021, + }, + }, + rules: { + // We use TypeScript for React components; prop-types are unnecessary + 'react/prop-types': 'off', + // General Best Practice Rules (subset adapted for flat config) + '@typescript-eslint/array-type': ['error', { default: 'array-simple' }], + 'arrow-body-style': ['error', 'as-needed'], + curly: ['error', 'multi-line'], + eqeqeq: ['error', 'always', { null: 'ignore' }], + '@typescript-eslint/consistent-type-assertions': [ + 'error', + { assertionStyle: 'as' }, + ], + '@typescript-eslint/explicit-member-accessibility': [ + 'error', + { accessibility: 'no-public' }, + ], + '@typescript-eslint/no-explicit-any': 'error', + '@typescript-eslint/no-inferrable-types': [ + 'error', + { ignoreParameters: true, ignoreProperties: true }, + ], + '@typescript-eslint/consistent-type-imports': [ + 'error', + { disallowTypeAnnotations: false }, + ], + '@typescript-eslint/no-namespace': ['error', { allowDeclarations: true }], + '@typescript-eslint/no-unused-vars': [ + 'error', + { + argsIgnorePattern: '^_', + varsIgnorePattern: '^_', + caughtErrorsIgnorePattern: '^_', + }, + ], + 'import/no-internal-modules': [ + 'error', + { + allow: [ + 'react-dom/test-utils', + 'react-dom/client', + 'memfs/lib/volume.js', + 'yargs/**', + 'msw/node', + '**/generated/**', + './styles/tailwind.css', + './styles/App.css', + './styles/style.css' + ], + }, + ], + 'import/no-relative-packages': 'error', + 'no-cond-assign': 'error', + 'no-debugger': 'error', + 'no-duplicate-case': 'error', + 'no-restricted-syntax': [ + 'error', + { + selector: 'CallExpression[callee.name="require"]', + message: 'Avoid using require(). Use ES6 imports instead.', + }, + { + selector: 'ThrowStatement > Literal:not([value=/^\\w+Error:/])', + message: + 'Do not throw string literals or non-Error objects. Throw new Error("...") instead.', + }, + ], + 'no-unsafe-finally': 'error', + 'no-unused-expressions': 'off', // Disable base rule + '@typescript-eslint/no-unused-expressions': [ + // Enable TS version + 'error', + { allowShortCircuit: true, allowTernary: true }, + ], + 'no-var': 'error', + 'object-shorthand': 'error', + 'one-var': ['error', 'never'], + 'prefer-arrow-callback': 'error', + 'prefer-const': ['error', { destructuring: 'all' }], + radix: 'error', + 'default-case': 'error', + }, +}, { + files: ['packages/*/src/**/*.test.{ts,tsx}', 'packages/**/test/**/*.test.{ts,tsx}'], + plugins: { + vitest, + }, + rules: { + ...vitest.configs.recommended.rules, + 'vitest/expect-expect': 'off', + 'vitest/no-commented-out-tests': 'off', + '@typescript-eslint/no-unused-vars': [ + 'error', + { + argsIgnorePattern: '^_', + varsIgnorePattern: '^_', + caughtErrorsIgnorePattern: '^_', + }, ], }, - eslint.configs.recommended, - ...tseslint.configs.recommended, - reactHooks.configs['recommended-latest'], - reactPlugin.configs.flat.recommended, - reactPlugin.configs.flat['jsx-runtime'], // Add this if you are using React 17+ - { - // Settings for eslint-plugin-react - settings: { - react: { - version: 'detect', +}, // extra settings for scripts that we run directly with node +{ + files: ['./scripts/**/*.js', 'esbuild.config.js', 'packages/*/scripts/**/*.js'], + languageOptions: { + globals: { + ...globals.node, + process: 'readonly', + console: 'readonly', + }, + }, + rules: { + '@typescript-eslint/no-unused-vars': [ + 'error', + { + argsIgnorePattern: '^_', + varsIgnorePattern: '^_', + caughtErrorsIgnorePattern: '^_', + }, + ], + }, +}, { + files: ['packages/vscode-ide-companion/esbuild.js'], + languageOptions: { + globals: { + ...globals.node, + process: 'readonly', + console: 'readonly', + }, + }, + rules: { + 'no-restricted-syntax': 'off', + '@typescript-eslint/no-require-imports': 'off', + }, +}, // extra settings for scripts that we run directly with node +{ + files: ['packages/vscode-ide-companion/scripts/**/*.js'], + languageOptions: { + globals: { + ...globals.node, + process: 'readonly', + console: 'readonly', + }, + }, + rules: { + 'no-restricted-syntax': 'off', + '@typescript-eslint/no-require-imports': 'off', + }, +}, // extra settings for core package scripts +{ + files: ['packages/core/scripts/**/*.js'], + languageOptions: { + globals: { + ...globals.node, + process: 'readonly', + console: 'readonly', + }, + }, + rules: { + 'no-restricted-syntax': 'off', + '@typescript-eslint/no-require-imports': 'off', + }, +}, // Prettier config must be last +prettierConfig, // extra settings for scripts that we run directly with node +{ + files: ['./integration-tests/**/*.{js,ts,tsx}'], + languageOptions: { + globals: { + ...globals.node, + process: 'readonly', + console: 'readonly', + }, + }, + rules: { + '@typescript-eslint/no-unused-vars': [ + 'error', + { + argsIgnorePattern: '^_', + varsIgnorePattern: '^_', + caughtErrorsIgnorePattern: '^_', + }, + ], + }, +}, // Settings for docs-site directory +{ + files: ['docs-site/**/*.{js,jsx}'], + languageOptions: { + globals: { + ...globals.browser, + ...globals.node, + }, + parserOptions: { + ecmaFeatures: { + jsx: true, }, }, }, - { - // Import specific config - files: ['packages/cli/src/**/*.{ts,tsx}'], // Target only TS/TSX in the cli package - plugins: { - import: importPlugin, - }, - settings: { - 'import/resolver': { - node: true, - }, - }, - rules: { - ...importPlugin.configs.recommended.rules, - ...importPlugin.configs.typescript.rules, - 'import/no-default-export': 'warn', - 'import/no-unresolved': 'off', // Disable for now, can be noisy with monorepos/paths - }, + rules: { + // Allow relaxed rules for documentation site + '@typescript-eslint/no-unused-vars': 'off', + 'react/prop-types': 'off', + 'react/react-in-jsx-scope': 'off', }, - { - // General overrides and rules for the project (TS/TSX files) - files: ['packages/*/src/**/*.{ts,tsx}'], // Target only TS/TSX in the cli package - plugins: { - import: importPlugin, - }, - settings: { - 'import/resolver': { - node: true, - }, - }, - languageOptions: { - globals: { - ...globals.node, - ...globals.es2021, - }, - }, - rules: { - // We use TypeScript for React components; prop-types are unnecessary - 'react/prop-types': 'off', - // General Best Practice Rules (subset adapted for flat config) - '@typescript-eslint/array-type': ['error', { default: 'array-simple' }], - 'arrow-body-style': ['error', 'as-needed'], - curly: ['error', 'multi-line'], - eqeqeq: ['error', 'always', { null: 'ignore' }], - '@typescript-eslint/consistent-type-assertions': [ - 'error', - { assertionStyle: 'as' }, - ], - '@typescript-eslint/explicit-member-accessibility': [ - 'error', - { accessibility: 'no-public' }, - ], - '@typescript-eslint/no-explicit-any': 'error', - '@typescript-eslint/no-inferrable-types': [ - 'error', - { ignoreParameters: true, ignoreProperties: true }, - ], - '@typescript-eslint/consistent-type-imports': [ - 'error', - { disallowTypeAnnotations: false }, - ], - '@typescript-eslint/no-namespace': ['error', { allowDeclarations: true }], - '@typescript-eslint/no-unused-vars': [ - 'error', - { - argsIgnorePattern: '^_', - varsIgnorePattern: '^_', - caughtErrorsIgnorePattern: '^_', - }, - ], - 'import/no-internal-modules': [ - 'error', - { - allow: [ - 'react-dom/test-utils', - 'react-dom/client', - 'memfs/lib/volume.js', - 'yargs/**', - 'msw/node', - '**/generated/**', - './styles/tailwind.css', - './styles/App.css', - './styles/style.css' - ], - }, - ], - 'import/no-relative-packages': 'error', - 'no-cond-assign': 'error', - 'no-debugger': 'error', - 'no-duplicate-case': 'error', - 'no-restricted-syntax': [ - 'error', - { - selector: 'CallExpression[callee.name="require"]', - message: 'Avoid using require(). Use ES6 imports instead.', - }, - { - selector: 'ThrowStatement > Literal:not([value=/^\\w+Error:/])', - message: - 'Do not throw string literals or non-Error objects. Throw new Error("...") instead.', - }, - ], - 'no-unsafe-finally': 'error', - 'no-unused-expressions': 'off', // Disable base rule - '@typescript-eslint/no-unused-expressions': [ - // Enable TS version - 'error', - { allowShortCircuit: true, allowTernary: true }, - ], - 'no-var': 'error', - 'object-shorthand': 'error', - 'one-var': ['error', 'never'], - 'prefer-arrow-callback': 'error', - 'prefer-const': ['error', { destructuring: 'all' }], - radix: 'error', - 'default-case': 'error', - }, - }, - { - files: ['packages/*/src/**/*.test.{ts,tsx}', 'packages/**/test/**/*.test.{ts,tsx}'], - plugins: { - vitest, - }, - rules: { - ...vitest.configs.recommended.rules, - 'vitest/expect-expect': 'off', - 'vitest/no-commented-out-tests': 'off', - '@typescript-eslint/no-unused-vars': [ - 'error', - { - argsIgnorePattern: '^_', - varsIgnorePattern: '^_', - caughtErrorsIgnorePattern: '^_', - }, - ], - }, - }, - // extra settings for scripts that we run directly with node - { - files: ['./scripts/**/*.js', 'esbuild.config.js', 'packages/*/scripts/**/*.js'], - languageOptions: { - globals: { - ...globals.node, - process: 'readonly', - console: 'readonly', - }, - }, - rules: { - '@typescript-eslint/no-unused-vars': [ - 'error', - { - argsIgnorePattern: '^_', - varsIgnorePattern: '^_', - caughtErrorsIgnorePattern: '^_', - }, - ], - }, - }, - { - files: ['packages/vscode-ide-companion/esbuild.js'], - languageOptions: { - globals: { - ...globals.node, - process: 'readonly', - console: 'readonly', - }, - }, - rules: { - 'no-restricted-syntax': 'off', - '@typescript-eslint/no-require-imports': 'off', - }, - }, - // extra settings for scripts that we run directly with node - { - files: ['packages/vscode-ide-companion/scripts/**/*.js'], - languageOptions: { - globals: { - ...globals.node, - process: 'readonly', - console: 'readonly', - }, - }, - rules: { - 'no-restricted-syntax': 'off', - '@typescript-eslint/no-require-imports': 'off', - }, - }, - // extra settings for core package scripts - { - files: ['packages/core/scripts/**/*.js'], - languageOptions: { - globals: { - ...globals.node, - process: 'readonly', - console: 'readonly', - }, - }, - rules: { - 'no-restricted-syntax': 'off', - '@typescript-eslint/no-require-imports': 'off', - }, - }, - // Prettier config must be last - prettierConfig, - // extra settings for scripts that we run directly with node - { - files: ['./integration-tests/**/*.{js,ts,tsx}'], - languageOptions: { - globals: { - ...globals.node, - process: 'readonly', - console: 'readonly', - }, - }, - rules: { - '@typescript-eslint/no-unused-vars': [ - 'error', - { - argsIgnorePattern: '^_', - varsIgnorePattern: '^_', - caughtErrorsIgnorePattern: '^_', - }, - ], - }, - }, - // Settings for docs-site directory - { - files: ['docs-site/**/*.{js,jsx}'], - languageOptions: { - globals: { - ...globals.browser, - ...globals.node, - }, - parserOptions: { - ecmaFeatures: { - jsx: true, - }, - }, - }, - rules: { - // Allow relaxed rules for documentation site - '@typescript-eslint/no-unused-vars': 'off', - 'react/prop-types': 'off', - 'react/react-in-jsx-scope': 'off', - }, - }, -); +}, storybook.configs["flat/recommended"]); diff --git a/package-lock.json b/package-lock.json index a5459d69d..371fa7682 100644 --- a/package-lock.json +++ b/package-lock.json @@ -67,6 +67,13 @@ "node-pty": "^1.0.0" } }, + "node_modules/@adobe/css-tools": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.4.tgz", + "integrity": "sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==", + "dev": true, + "license": "MIT" + }, "node_modules/@alcalzone/ansi-tokenize": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/@alcalzone/ansi-tokenize/-/ansi-tokenize-0.2.0.tgz", @@ -375,12 +382,12 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.28.6.tgz", + "integrity": "sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==", "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" }, @@ -394,6 +401,183 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "license": "MIT" }, + "node_modules/@babel/compat-data": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.6.tgz", + "integrity": "sha512-2lfu57JtzctfIrcGMz992hyLlByuzgIk58+hhGCxjKZ3rWI82NnVLjXcaTqkI2NvlcvOskZaiZ5kjUALo3Lpxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.6.tgz", + "integrity": "sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/generator": "^7.28.6", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.6.tgz", + "integrity": "sha512-lOoVRwADj8hjf7al89tvQ2a1lf53Z+7tiXMgpZJL3maQPDxh0DgLMN62B2MKUOFcoodBHLMbDM6WAbKgNy5Suw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", + "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-string-parser": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", @@ -405,22 +589,46 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", - "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/parser": { - "version": "7.27.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.5.tgz", - "integrity": "sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==", + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz", + "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.27.3" + "@babel/template": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.6.tgz", + "integrity": "sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.6" }, "bin": { "parser": "bin/babel-parser.js" @@ -429,6 +637,38 @@ "node": ">=6.0.0" } }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/runtime": { "version": "7.27.6", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.6.tgz", @@ -438,15 +678,49 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/template": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.6.tgz", + "integrity": "sha512-fgWX62k02qtjqdSNTAGxmKYY/7FSL9WAS1o2Hu5+I5m9T0yxZzr4cnrfXQ/MX0rIifthCSs6FKTlzYbJcPtMNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/generator": "^7.28.6", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.6", + "@babel/template": "^7.28.6", + "@babel/types": "^7.28.6", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/types": { - "version": "7.27.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.6.tgz", - "integrity": "sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.6.tgz", + "integrity": "sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" + "@babel/helper-validator-identifier": "^7.28.5" }, "engines": { "node": ">=6.9.0" @@ -509,6 +783,27 @@ "node": ">=6" } }, + "node_modules/@chromatic-com/storybook": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@chromatic-com/storybook/-/storybook-5.0.0.tgz", + "integrity": "sha512-8wUsqL8kg6R5ue8XNE7Jv/iD1SuE4+6EXMIGIuE+T2loBITEACLfC3V8W44NJviCLusZRMWbzICddz0nU0bFaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@neoconfetti/react": "^1.0.0", + "chromatic": "^13.3.4", + "filesize": "^10.0.12", + "jsonfile": "^6.1.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=20.0.0", + "yarn": ">=1.22.18" + }, + "peerDependencies": { + "storybook": "^0.0.0-0 || ^10.1.0 || ^10.1.0-0 || ^10.2.0-0 || ^10.3.0-0" + } + }, "node_modules/@csstools/color-helpers": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.0.2.tgz", @@ -1558,19 +1853,129 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", - "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "node_modules/@joshwooding/vite-plugin-react-docgen-typescript": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@joshwooding/vite-plugin-react-docgen-typescript/-/vite-plugin-react-docgen-typescript-0.6.3.tgz", + "integrity": "sha512-9TGZuAX+liGkNKkwuo3FYJu7gHWT0vkBcf7GkOe7s7fmC19XwH/4u5u7sDIFrMooe558ORcmuBvBz7Ur5PlbHw==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" + "glob": "^11.1.0", + "react-docgen-typescript": "^2.2.2" + }, + "peerDependencies": { + "typescript": ">= 4.3.x", + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@joshwooding/vite-plugin-react-docgen-typescript/node_modules/glob": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz", + "integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "foreground-child": "^3.3.1", + "jackspeak": "^4.1.1", + "minimatch": "^10.1.1", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" }, "engines": { - "node": ">=6.0.0" + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@joshwooding/vite-plugin-react-docgen-typescript/node_modules/jackspeak": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz", + "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@joshwooding/vite-plugin-react-docgen-typescript/node_modules/lru-cache": { + "version": "11.2.4", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", + "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@joshwooding/vite-plugin-react-docgen-typescript/node_modules/minimatch": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@joshwooding/vite-plugin-react-docgen-typescript/node_modules/path-scurry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", + "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" } }, "node_modules/@jridgewell/resolve-uri": { @@ -1583,16 +1988,6 @@ "node": ">=6.0.0" } }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", @@ -1601,9 +1996,9 @@ "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "dev": true, "license": "MIT", "dependencies": { @@ -1848,6 +2243,158 @@ "win32" ] }, + "node_modules/@mdx-js/react": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.1.tgz", + "integrity": "sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdx": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "@types/react": ">=16", + "react": ">=16" + } + }, + "node_modules/@microsoft/api-extractor": { + "version": "7.43.0", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.43.0.tgz", + "integrity": "sha512-GFhTcJpB+MI6FhvXEI9b2K0snulNLWHqC/BbcJtyNYcKUiw7l3Lgis5ApsYncJ0leALX7/of4XfmXk+maT111w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@microsoft/api-extractor-model": "7.28.13", + "@microsoft/tsdoc": "0.14.2", + "@microsoft/tsdoc-config": "~0.16.1", + "@rushstack/node-core-library": "4.0.2", + "@rushstack/rig-package": "0.5.2", + "@rushstack/terminal": "0.10.0", + "@rushstack/ts-command-line": "4.19.1", + "lodash": "~4.17.15", + "minimatch": "~3.0.3", + "resolve": "~1.22.1", + "semver": "~7.5.4", + "source-map": "~0.6.1", + "typescript": "5.4.2" + }, + "bin": { + "api-extractor": "bin/api-extractor" + } + }, + "node_modules/@microsoft/api-extractor-model": { + "version": "7.28.13", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.13.tgz", + "integrity": "sha512-39v/JyldX4MS9uzHcdfmjjfS6cYGAoXV+io8B5a338pkHiSt+gy2eXQ0Q7cGFJ7quSa1VqqlMdlPrB6sLR/cAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@microsoft/tsdoc": "0.14.2", + "@microsoft/tsdoc-config": "~0.16.1", + "@rushstack/node-core-library": "4.0.2" + } + }, + "node_modules/@microsoft/api-extractor/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@microsoft/api-extractor/node_modules/minimatch": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", + "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@microsoft/api-extractor/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@microsoft/api-extractor/node_modules/typescript": { + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", + "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/@microsoft/api-extractor/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/@microsoft/tsdoc": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.14.2.tgz", + "integrity": "sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==", + "dev": true, + "license": "MIT" + }, + "node_modules/@microsoft/tsdoc-config": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.16.2.tgz", + "integrity": "sha512-OGiIzzoBLgWWR0UdRJX98oYO+XKGf7tiK4Zk6tQ/E4IJqGCe7dvkTvgDZV5cFJUzLGDOjeAXrnZoA6QkVySuxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@microsoft/tsdoc": "0.14.2", + "ajv": "~6.12.6", + "jju": "~1.4.0", + "resolve": "~1.19.0" + } + }, + "node_modules/@microsoft/tsdoc-config/node_modules/resolve": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.1.0", + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/@mswjs/interceptors": { "version": "0.39.5", "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.39.5.tgz", @@ -1866,6 +2413,13 @@ "node": ">=18" } }, + "node_modules/@neoconfetti/react": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@neoconfetti/react/-/react-1.0.0.tgz", + "integrity": "sha512-klcSooChXXOzIm+SE5IISIAn3bYzYfPjbX7D7HoqZL84oAfgREeSg5vSIaSFH+DaGzzvImTyWe1OyrJ67vik4A==", + "dev": true, + "license": "MIT" + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -2839,6 +3393,13 @@ "node": ">=12" } }, + "node_modules/@polka/url": { + "version": "1.0.0-next.29", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", + "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", + "dev": true, + "license": "MIT" + }, "node_modules/@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", @@ -2919,6 +3480,60 @@ "resolved": "packages/sdk-typescript", "link": true }, + "node_modules/@qwen-code/webui": { + "resolved": "packages/webui", + "link": true + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.27", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", + "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/pluginutils": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", + "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/pluginutils/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.44.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.44.0.tgz", @@ -3206,6 +3821,169 @@ "dev": true, "license": "MIT" }, + "node_modules/@rushstack/node-core-library": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.0.2.tgz", + "integrity": "sha512-hyES82QVpkfQMeBMteQUnrhASL/KHPhd7iJ8euduwNJG4mu2GSOKybf0rOEjOm1Wz7CwJEUm9y0yD7jg2C1bfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fs-extra": "~7.0.1", + "import-lazy": "~4.0.0", + "jju": "~1.4.0", + "resolve": "~1.22.1", + "semver": "~7.5.4", + "z-schema": "~5.0.2" + }, + "peerDependencies": { + "@types/node": "*" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@rushstack/node-core-library/node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/@rushstack/node-core-library/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@rushstack/node-core-library/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@rushstack/node-core-library/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@rushstack/node-core-library/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/@rushstack/node-core-library/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/@rushstack/rig-package": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.5.2.tgz", + "integrity": "sha512-mUDecIJeH3yYGZs2a48k+pbhM6JYwWlgjs2Ca5f2n1G2/kgdgP9D/07oglEGf6mRyXEnazhEENeYTSNDRCwdqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve": "~1.22.1", + "strip-json-comments": "~3.1.1" + } + }, + "node_modules/@rushstack/terminal": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.10.0.tgz", + "integrity": "sha512-UbELbXnUdc7EKwfH2sb8ChqNgapUOdqcCIdQP4NGxBpTZV2sQyeekuK3zmfQSa/MN+/7b4kBogl2wq0vpkpYGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rushstack/node-core-library": "4.0.2", + "supports-color": "~8.1.1" + }, + "peerDependencies": { + "@types/node": "*" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@rushstack/terminal/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/@rushstack/ts-command-line": { + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.19.1.tgz", + "integrity": "sha512-J7H768dgcpG60d7skZ5uSSwyCZs/S2HrWP1Ds8d1qYAyaaeJmpmmLr9BVw97RjFzmQPOYnoXcKA4GkqDCkduQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rushstack/terminal": "0.10.0", + "@types/argparse": "1.0.38", + "argparse": "~1.0.9", + "string-argv": "~0.3.1" + } + }, + "node_modules/@rushstack/ts-command-line/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, "node_modules/@secretlint/config-creator": { "version": "10.2.2", "resolved": "https://registry.npmjs.org/@secretlint/config-creator/-/config-creator-10.2.2.tgz", @@ -3424,6 +4202,269 @@ "dev": true, "license": "MIT" }, + "node_modules/@storybook/addon-a11y": { + "version": "10.1.11", + "resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-10.1.11.tgz", + "integrity": "sha512-3sr6HmcDgW1+TQAV9QtWBE3HlGyfFXVZY3RECTNLNH6fRC+rYQCItisvQIVxQpyftLSQ8EAMN9JQzs495MjWNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "axe-core": "^4.2.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^10.1.11" + } + }, + "node_modules/@storybook/addon-docs": { + "version": "10.1.11", + "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-10.1.11.tgz", + "integrity": "sha512-Jwm291Fhim2eVcZIVlkG1B2skb0ZI9oru6nqMbJxceQZlvZmcIa4oxvS1oaMTKw2DJnCv97gLm57P/YvRZ8eUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@mdx-js/react": "^3.0.0", + "@storybook/csf-plugin": "10.1.11", + "@storybook/icons": "^2.0.0", + "@storybook/react-dom-shim": "10.1.11", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^10.1.11" + } + }, + "node_modules/@storybook/addon-onboarding": { + "version": "10.1.11", + "resolved": "https://registry.npmjs.org/@storybook/addon-onboarding/-/addon-onboarding-10.1.11.tgz", + "integrity": "sha512-DNJv0IDl5XBrY+PPgwnMXLyp3omPkMOS6xe8ejG3csT71B6+3VueL6m7Qivh6739SnAV0QBU5SQlpMA0gQUcSA==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^10.1.11" + } + }, + "node_modules/@storybook/addon-vitest": { + "version": "10.1.11", + "resolved": "https://registry.npmjs.org/@storybook/addon-vitest/-/addon-vitest-10.1.11.tgz", + "integrity": "sha512-YbZzeKO3v+Xr97/malT4DZIATkVZT5EHNYx3xzEfPVuk19dDETAVYXO+tzcqCQHsgdKQHkmd56vv8nN3J3/kvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "@storybook/icons": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "@vitest/browser": "^3.0.0 || ^4.0.0", + "@vitest/browser-playwright": "^4.0.0", + "@vitest/runner": "^3.0.0 || ^4.0.0", + "storybook": "^10.1.11", + "vitest": "^3.0.0 || ^4.0.0" + }, + "peerDependenciesMeta": { + "@vitest/browser": { + "optional": true + }, + "@vitest/browser-playwright": { + "optional": true + }, + "@vitest/runner": { + "optional": true + }, + "vitest": { + "optional": true + } + } + }, + "node_modules/@storybook/builder-vite": { + "version": "10.1.11", + "resolved": "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-10.1.11.tgz", + "integrity": "sha512-MMD09Ap7FyzDfWG961pkIMv/w684XXe1bBEi+wCEpHxvrgAd3j3A9w/Rqp9Am2uRDPCEdi1QgSzS3SGW3aGThQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/csf-plugin": "10.1.11", + "@vitest/mocker": "3.2.4", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^10.1.11", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/@storybook/csf-plugin": { + "version": "10.1.11", + "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-10.1.11.tgz", + "integrity": "sha512-Ant0NhgqHKzQsseeVTSetZCuDHHs0W2HRkHt51Kg/sUl0T/sDtfVA+fWZT8nGzGZqYSFkxqYPWjauPmIhPtaRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "unplugin": "^2.3.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "esbuild": "*", + "rollup": "*", + "storybook": "^10.1.11", + "vite": "*", + "webpack": "*" + }, + "peerDependenciesMeta": { + "esbuild": { + "optional": true + }, + "rollup": { + "optional": true + }, + "vite": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/@storybook/global": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@storybook/global/-/global-5.0.0.tgz", + "integrity": "sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@storybook/icons": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@storybook/icons/-/icons-2.0.1.tgz", + "integrity": "sha512-/smVjw88yK3CKsiuR71vNgWQ9+NuY2L+e8X7IMrFjexjm6ZR8ULrV2DRkTA61aV6ryefslzHEGDInGpnNeIocg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@storybook/react": { + "version": "10.1.11", + "resolved": "https://registry.npmjs.org/@storybook/react/-/react-10.1.11.tgz", + "integrity": "sha512-rmMGmEwBaM2YpB8oDk2moM0MNjNMqtwyoPPZxjyruY9WVhYca8EDPGKEdRzUlb4qZJsTgLi7VU4eqg6LD/mL3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "@storybook/react-dom-shim": "10.1.11", + "react-docgen": "^8.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "storybook": "^10.1.11", + "typescript": ">= 4.9.x" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@storybook/react-dom-shim": { + "version": "10.1.11", + "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-10.1.11.tgz", + "integrity": "sha512-o8WPhRlZbORUWG9lAgDgJP0pi905VHJUFJr1Kp8980gHqtlemtnzjPxKy5vFwj6glNhAlK8SS8OOYzWP7hloTQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "storybook": "^10.1.11" + } + }, + "node_modules/@storybook/react-vite": { + "version": "10.1.11", + "resolved": "https://registry.npmjs.org/@storybook/react-vite/-/react-vite-10.1.11.tgz", + "integrity": "sha512-qh1BCD25nIoiDfqwha+qBkl7pcG4WuzM+c8tsE63YEm8AFIbNKg5K8lVUoclF+4CpFz7IwBpWe61YUTDfp+91w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@joshwooding/vite-plugin-react-docgen-typescript": "^0.6.3", + "@rollup/pluginutils": "^5.0.2", + "@storybook/builder-vite": "10.1.11", + "@storybook/react": "10.1.11", + "empathic": "^2.0.0", + "magic-string": "^0.30.0", + "react-docgen": "^8.0.0", + "resolve": "^1.22.8", + "tsconfig-paths": "^4.2.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "storybook": "^10.1.11", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/@storybook/react-vite/node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@storybook/react-vite/node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/@testing-library/dom": { "version": "10.4.1", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", @@ -3475,6 +4516,47 @@ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "license": "MIT" }, + "node_modules/@testing-library/jest-dom": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz", + "integrity": "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@adobe/css-tools": "^4.4.0", + "aria-query": "^5.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "picocolors": "^1.1.1", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@testing-library/user-event": { + "version": "14.6.1", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.1.tgz", + "integrity": "sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" + } + }, "node_modules/@textlint/ast-node-types": { "version": "15.2.2", "resolved": "https://registry.npmjs.org/@textlint/ast-node-types/-/ast-node-types-15.2.2.tgz", @@ -3605,12 +4687,64 @@ "@types/readdir-glob": "*" } }, + "node_modules/@types/argparse": { + "version": "1.0.38", + "resolved": "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz", + "integrity": "sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/aria-query": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", "license": "MIT" }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, "node_modules/@types/body-parser": { "version": "1.19.6", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", @@ -3686,6 +4820,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/doctrine": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/@types/doctrine/-/doctrine-0.0.9.tgz", + "integrity": "sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/dotenv": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/@types/dotenv/-/dotenv-6.1.1.tgz", @@ -3812,6 +4953,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/mdx": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", + "integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/mime": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", @@ -3933,6 +5081,13 @@ "@types/node": "*" } }, + "node_modules/@types/resolve": { + "version": "1.20.6", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.6.tgz", + "integrity": "sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/sarif": { "version": "2.1.7", "resolved": "https://registry.npmjs.org/@types/sarif/-/sarif-2.1.7.tgz", @@ -4357,6 +5512,63 @@ "dev": true, "license": "ISC" }, + "node_modules/@vitejs/plugin-react": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", + "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.0", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.27", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.17.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/@vitest/browser": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/browser/-/browser-3.2.4.tgz", + "integrity": "sha512-tJxiPrWmzH8a+w9nLKlQMzAKX/7VjFs50MWgcAj7p9XQ7AQ9/35fByFYptgPELyLw+0aixTnC4pUWV+APcZ/kw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@testing-library/dom": "^10.4.0", + "@testing-library/user-event": "^14.6.1", + "@vitest/mocker": "3.2.4", + "@vitest/utils": "3.2.4", + "magic-string": "^0.30.17", + "sirv": "^3.0.1", + "tinyrainbow": "^2.0.0", + "ws": "^8.18.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "playwright": "*", + "vitest": "3.2.4", + "webdriverio": "^7.0.0 || ^8.0.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "playwright": { + "optional": true + }, + "safaridriver": { + "optional": true + }, + "webdriverio": { + "optional": true + } + } + }, "node_modules/@vitest/coverage-v8": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.2.4.tgz", @@ -4529,6 +5741,37 @@ "url": "https://opencollective.com/vitest" } }, + "node_modules/@volar/language-core": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-1.11.1.tgz", + "integrity": "sha512-dOcNn3i9GgZAcJt43wuaEykSluAuOkQgzni1cuxLxTV0nJKanQztp7FxyswdRILaKH+P2XZMPRp2S4MV/pElCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/source-map": "1.11.1" + } + }, + "node_modules/@volar/source-map": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-1.11.1.tgz", + "integrity": "sha512-hJnOnwZ4+WT5iupLRnuzbULZ42L7BWWPMmruzwtLhJfpDVoZLjNBxHDi2sY2bgZXCKlpU5XcsMFoYrsQmPhfZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "muggle-string": "^0.3.1" + } + }, + "node_modules/@volar/typescript": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-1.11.1.tgz", + "integrity": "sha512-iU+t2mas/4lYierSnoFOeRFQUhAEMgsFuQxoxvwn5EdQopw43j+J27a4lt9LMInx1gLJBC6qL14WYGlgymaSMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/language-core": "1.11.1", + "path-browserify": "^1.0.1" + } + }, "node_modules/@vscode/vsce": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/@vscode/vsce/-/vsce-3.6.0.tgz", @@ -4850,6 +6093,110 @@ "dev": true, "license": "ISC" }, + "node_modules/@vue/compiler-core": { + "version": "3.5.26", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.26.tgz", + "integrity": "sha512-vXyI5GMfuoBCnv5ucIT7jhHKl55Y477yxP6fc4eUswjP8FG3FFVFd41eNDArR+Uk3QKn2Z85NavjaxLxOC19/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@vue/shared": "3.5.26", + "entities": "^7.0.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-core/node_modules/entities": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.0.tgz", + "integrity": "sha512-FDWG5cmEYf2Z00IkYRhbFrwIwvdFKH07uV8dvNy0omp/Qb1xcyCWp2UDtcwJF4QZZvk0sLudP6/hAu42TaqVhQ==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/@vue/compiler-core/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vue/compiler-dom": { + "version": "3.5.26", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.26.tgz", + "integrity": "sha512-y1Tcd3eXs834QjswshSilCBnKGeQjQXB6PqFn/1nxcQw4pmG42G8lwz+FZPAZAby6gZeHSt/8LMPfZ4Rb+Bd/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/compiler-core": "3.5.26", + "@vue/shared": "3.5.26" + } + }, + "node_modules/@vue/language-core": { + "version": "1.8.27", + "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-1.8.27.tgz", + "integrity": "sha512-L8Kc27VdQserNaCUNiSFdDl9LWT24ly8Hpwf1ECy3aFb9m6bDhBGQYOujDm21N7EW3moKIOKEanQwe1q5BK+mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/language-core": "~1.11.1", + "@volar/source-map": "~1.11.1", + "@vue/compiler-dom": "^3.3.0", + "@vue/shared": "^3.3.0", + "computeds": "^0.0.1", + "minimatch": "^9.0.3", + "muggle-string": "^0.3.1", + "path-browserify": "^1.0.1", + "vue-template-compiler": "^2.7.14" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@vue/language-core/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@vue/language-core/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.26", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.26.tgz", + "integrity": "sha512-7Z6/y3uFI5PRoKeorTOSXKcDj0MSasfNNltcslbFrPpcw6aXRUALq4IfJlaTRspiWIUOEZbrpM+iQGmCOiWe4A==", + "dev": true, + "license": "MIT" + }, "node_modules/@xterm/headless": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/@xterm/headless/-/headless-5.5.0.tgz", @@ -5477,6 +6824,19 @@ "node": ">=12" } }, + "node_modules/ast-types": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz", + "integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/ast-v8-to-istanbul": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.3.tgz", @@ -5606,6 +6966,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/axe-core": { + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.11.1.tgz", + "integrity": "sha512-BASOg+YwO2C+346x3LZOeoovTIoTrRqEsqMa6fmfAV0P+U9mFr9NsyOEpiYvFjbc64NMrSswhV50WdXzdb/Z5A==", + "dev": true, + "license": "MPL-2.0", + "engines": { + "node": ">=4" + } + }, "node_modules/azure-devops-node-api": { "version": "12.5.0", "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-12.5.0.tgz", @@ -6236,6 +7606,30 @@ "node": ">=18" } }, + "node_modules/chromatic": { + "version": "13.3.5", + "resolved": "https://registry.npmjs.org/chromatic/-/chromatic-13.3.5.tgz", + "integrity": "sha512-MzPhxpl838qJUo0A55osCF2ifwPbjcIPeElr1d4SHcjnHoIcg7l1syJDrAYK/a+PcCBrOGi06jPNpQAln5hWgw==", + "dev": true, + "license": "MIT", + "bin": { + "chroma": "dist/bin.js", + "chromatic": "dist/bin.js", + "chromatic-cli": "dist/bin.js" + }, + "peerDependencies": { + "@chromatic-com/cypress": "^0.*.* || ^1.0.0", + "@chromatic-com/playwright": "^0.*.* || ^1.0.0" + }, + "peerDependenciesMeta": { + "@chromatic-com/cypress": { + "optional": true + }, + "@chromatic-com/playwright": { + "optional": true + } + } + }, "node_modules/cjs-module-lexer": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", @@ -6583,6 +7977,13 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/computeds": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/computeds/-/computeds-0.0.1.tgz", + "integrity": "sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==", + "dev": true, + "license": "MIT" + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -6653,6 +8054,13 @@ "node": ">= 0.6" } }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, "node_modules/convert-to-spaces": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/convert-to-spaces/-/convert-to-spaces-2.0.1.tgz", @@ -6828,6 +8236,13 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "dev": true, + "license": "MIT" + }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -6939,6 +8354,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/de-indent": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", + "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", + "dev": true, + "license": "MIT" + }, "node_modules/debug": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", @@ -7417,6 +8839,16 @@ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "license": "MIT" }, + "node_modules/empathic": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/empathic/-/empathic-2.0.0.tgz", + "integrity": "sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, "node_modules/encodeurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", @@ -8020,6 +9452,20 @@ "semver": "bin/semver.js" } }, + "node_modules/eslint-plugin-storybook": { + "version": "10.1.11", + "resolved": "https://registry.npmjs.org/eslint-plugin-storybook/-/eslint-plugin-storybook-10.1.11.tgz", + "integrity": "sha512-mbq2r2kK5+AcLl0XDJ3to91JOgzCbHOqj+J3n+FRw6drk+M1boRqMShSoMMm0HdzXPLmlr7iur+qJ5ZuhH6ayQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/utils": "^8.8.1" + }, + "peerDependencies": { + "eslint": ">=8", + "storybook": "^10.1.11" + } + }, "node_modules/eslint-scope": { "version": "8.4.0", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", @@ -8550,6 +9996,16 @@ "node": ">=16.0.0" } }, + "node_modules/filesize": { + "version": "10.1.6", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-10.1.6.tgz", + "integrity": "sha512-sJslQKU2uM33qH5nqewAwVB2QgR6w1aMNsYUp3aN5rMRyXEwJGmZvaWzeJFNTOXWlHQyBFCWrdj3fV/fsTOX8w==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 10.4.0" + } + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -8898,6 +10354,16 @@ "integrity": "sha512-Tt4kuxLXFKHy8KT40zwsUPUkg1CrsgY25FxA2U/j/0WgEDCk3ddc/zLTCCcbSHX9FcKtLuVaDGtGE/STWC+j3Q==", "license": "BSD-3-Clause" }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -9354,6 +10820,16 @@ "node": ">= 0.4" } }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, "node_modules/headers-polyfill": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/headers-polyfill/-/headers-polyfill-4.0.3.tgz", @@ -9625,6 +11101,16 @@ "module-details-from-path": "^1.0.3" } }, + "node_modules/import-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -10690,6 +12176,13 @@ "jiti": "bin/jiti.js" } }, + "node_modules/jju": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", + "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==", + "dev": true, + "license": "MIT" + }, "node_modules/jose": { "version": "6.1.3", "resolved": "https://registry.npmjs.org/jose/-/jose-6.1.3.tgz", @@ -10759,6 +12252,19 @@ } } }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/json": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/json/-/json-11.0.0.tgz", @@ -10981,6 +12487,13 @@ "json-buffer": "3.0.1" } }, + "node_modules/kolorist": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", + "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==", + "dev": true, + "license": "MIT" + }, "node_modules/ky": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/ky/-/ky-1.8.1.tgz", @@ -11315,6 +12828,14 @@ "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", "license": "MIT" }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "deprecated": "This package is deprecated. Use the optional chaining (?.) operator instead.", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.includes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", @@ -11329,6 +12850,14 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", + "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.isinteger": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", @@ -11723,6 +13252,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -11812,6 +13351,16 @@ "integrity": "sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==", "license": "MIT" }, + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -11883,6 +13432,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/muggle-string": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.3.1.tgz", + "integrity": "sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==", + "dev": true, + "license": "MIT" + }, "node_modules/mute-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", @@ -12629,15 +14185,15 @@ } }, "node_modules/open": { - "version": "10.1.2", - "resolved": "https://registry.npmjs.org/open/-/open-10.1.2.tgz", - "integrity": "sha512-cxN6aIDPz6rm8hbebcP7vrQNhvRcveZoJU72Y7vskh4oIm+BZwBECnx5nTmrlres1Qapvx27Qo1Auukpf8PKXw==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz", + "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==", "license": "MIT", "dependencies": { "default-browser": "^5.2.1", "define-lazy-prop": "^3.0.0", "is-inside-container": "^1.0.0", - "is-wsl": "^3.1.0" + "wsl-utils": "^0.1.0" }, "engines": { "node": ">=18" @@ -12925,6 +14481,13 @@ "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true, + "license": "MIT" + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -13101,6 +14664,54 @@ "pathe": "^2.0.1" } }, + "node_modules/playwright": { + "version": "1.57.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.57.0.tgz", + "integrity": "sha512-ilYQj1s8sr2ppEJ2YVadYBN0Mb3mdo9J0wQ+UuDhzYqURwSoW4n1Xs5vs7ORwgDGmyEh33tRMeS8KhdkMoLXQw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.57.0" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.57.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.57.0.tgz", + "integrity": "sha512-agTcKlMw/mjBWOnD6kFZttAAGHgi/Nw0CZ2o6JqWSbMlI219lAFLZZCyqByTsvVAJq5XA5H8cA6PrvBRpBWEuQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/playwright/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/pluralize": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", @@ -13678,11 +15289,55 @@ } } }, + "node_modules/react-docgen": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/react-docgen/-/react-docgen-8.0.2.tgz", + "integrity": "sha512-+NRMYs2DyTP4/tqWz371Oo50JqmWltR1h2gcdgUMAWZJIAvrd0/SqlCfx7tpzpl/s36rzw6qH2MjoNrxtRNYhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.0", + "@babel/traverse": "^7.28.0", + "@babel/types": "^7.28.2", + "@types/babel__core": "^7.20.5", + "@types/babel__traverse": "^7.20.7", + "@types/doctrine": "^0.0.9", + "@types/resolve": "^1.20.2", + "doctrine": "^3.0.0", + "resolve": "^1.22.1", + "strip-indent": "^4.0.0" + }, + "engines": { + "node": "^20.9.0 || >=22" + } + }, + "node_modules/react-docgen-typescript": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/react-docgen-typescript/-/react-docgen-typescript-2.4.0.tgz", + "integrity": "sha512-ZtAp5XTO5HRzQctjPU0ybY0RRCQO19X/8fxn3w7y2VVTUbGHDKULPTL4ky3vB05euSgG5NpALhEhDPvQ56wvXg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "typescript": ">= 4.3.x" + } + }, + "node_modules/react-docgen/node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/react-dom": { "version": "19.1.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", - "dev": true, "license": "MIT", "dependencies": { "scheduler": "^0.26.0" @@ -13712,6 +15367,16 @@ "react": "^19.1.0" } }, + "node_modules/react-refresh": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/read": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", @@ -13888,6 +15553,60 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/recast": { + "version": "0.23.11", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.11.tgz", + "integrity": "sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ast-types": "^0.16.1", + "esprima": "~4.0.0", + "source-map": "~0.6.1", + "tiny-invariant": "^1.3.3", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/redent/node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/redent/node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/reflect.getprototypeof": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", @@ -14747,6 +16466,21 @@ "url": "https://github.com/steveukx/git-js?sponsor=1" } }, + "node_modules/sirv": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz", + "integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/slash": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", @@ -14803,6 +16537,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -14910,6 +16654,42 @@ "node": ">= 0.4" } }, + "node_modules/storybook": { + "version": "10.1.11", + "resolved": "https://registry.npmjs.org/storybook/-/storybook-10.1.11.tgz", + "integrity": "sha512-pKP5jXJYM4OjvNklGuHKO53wOCAwfx79KvZyOWHoi9zXUH5WVMFUe/ZfWyxXG/GTcj0maRgHGUjq/0I43r0dDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "@storybook/icons": "^2.0.0", + "@testing-library/jest-dom": "^6.6.3", + "@testing-library/user-event": "^14.6.1", + "@vitest/expect": "3.2.4", + "@vitest/spy": "3.2.4", + "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0 || ^0.26.0 || ^0.27.0", + "open": "^10.2.0", + "recast": "^0.23.5", + "semver": "^7.6.2", + "use-sync-external-store": "^1.5.0", + "ws": "^8.18.0" + }, + "bin": { + "storybook": "dist/bin/dispatcher.js" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "prettier": "^2 || ^3" + }, + "peerDependenciesMeta": { + "prettier": { + "optional": true + } + } + }, "node_modules/streamx": { "version": "2.23.0", "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.23.0.tgz", @@ -15167,6 +16947,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/strip-indent": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.1.1.tgz", + "integrity": "sha512-SlyRoSkdh1dYP0PzclLE7r0M9sgbFKKMFXpFRUMNuKhQSbC6VQIGzq3E0qsfvGJaUFJPGv6Ws1NZ/haTAjfbMA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -15688,6 +17481,13 @@ "integrity": "sha512-PKvy1rVF1RibfF3JlXBSP0Jrcw2uq3yXdgcEXtKTYn3QJ/cBRBHDnrJ5jHky+MENZ6DIPwNUGWpkVx+7joCpNA==", "license": "MIT" }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "dev": true, + "license": "MIT" + }, "node_modules/tinybench": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", @@ -15845,6 +17645,16 @@ "node": ">=0.6" } }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/tough-cookie": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz", @@ -15901,6 +17711,16 @@ "typescript": ">=4.8.4" } }, + "node_modules/ts-dedent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", + "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.10" + } + }, "node_modules/ts-interface-checker": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", @@ -16244,6 +18064,35 @@ "node": ">= 0.8" } }, + "node_modules/unplugin": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-2.3.11.tgz", + "integrity": "sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "acorn": "^8.15.0", + "picomatch": "^4.0.3", + "webpack-virtual-modules": "^0.6.2" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/unplugin/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/update-browserslist-db": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz", @@ -16423,6 +18272,16 @@ "requires-port": "^1.0.0" } }, + "node_modules/use-sync-external-store": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -16463,6 +18322,16 @@ "spdx-expression-parse": "^3.0.0" } }, + "node_modules/validator": { + "version": "13.15.26", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.26.tgz", + "integrity": "sha512-spH26xU080ydGggxRyR1Yhcbgx+j3y5jbNXk/8L+iRvdIEQ4uTRH2Sgf2dokud6Q4oAtsbNvJ1Ft+9xmm6IZcA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -16583,6 +18452,34 @@ "url": "https://opencollective.com/vitest" } }, + "node_modules/vite-plugin-dts": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/vite-plugin-dts/-/vite-plugin-dts-3.9.1.tgz", + "integrity": "sha512-rVp2KM9Ue22NGWB8dNtWEr+KekN3rIgz1tWD050QnRGlriUCmaDwa7qA5zDEjbXg5lAXhYMSBJtx3q3hQIJZSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@microsoft/api-extractor": "7.43.0", + "@rollup/pluginutils": "^5.1.0", + "@vue/language-core": "^1.8.27", + "debug": "^4.3.4", + "kolorist": "^1.8.0", + "magic-string": "^0.30.8", + "vue-tsc": "^1.8.27" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "typescript": "*", + "vite": "*" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, "node_modules/vite/node_modules/fdir": { "version": "6.4.6", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", @@ -16697,6 +18594,35 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/vue-template-compiler": { + "version": "2.7.16", + "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.16.tgz", + "integrity": "sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "de-indent": "^1.0.2", + "he": "^1.2.0" + } + }, + "node_modules/vue-tsc": { + "version": "1.8.27", + "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-1.8.27.tgz", + "integrity": "sha512-WesKCAZCRAbmmhuGl3+VrdWItEvfoFIPXOvUJkjULi+x+6G/Dy69yO3TBRJDr9eUlmsNAwVmxsNZxvHKzbkKdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/typescript": "~1.11.1", + "@vue/language-core": "1.8.27", + "semver": "^7.5.4" + }, + "bin": { + "vue-tsc": "bin/vue-tsc.js" + }, + "peerDependencies": { + "typescript": "*" + } + }, "node_modules/w3c-xmlserializer": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", @@ -16729,6 +18655,13 @@ "node": ">=12" } }, + "node_modules/webpack-virtual-modules": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz", + "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==", + "dev": true, + "license": "MIT" + }, "node_modules/whatwg-encoding": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", @@ -17047,6 +18980,21 @@ } } }, + "node_modules/wsl-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz", + "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", + "license": "MIT", + "dependencies": { + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/xdg-basedir": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz", @@ -17242,6 +19190,38 @@ "integrity": "sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==", "license": "MIT" }, + "node_modules/z-schema": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-5.0.5.tgz", + "integrity": "sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash.get": "^4.4.2", + "lodash.isequal": "^4.5.0", + "validator": "^13.7.0" + }, + "bin": { + "z-schema": "bin/z-schema" + }, + "engines": { + "node": ">=8.0.0" + }, + "optionalDependencies": { + "commander": "^9.4.1" + } + }, + "node_modules/z-schema/node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": "^12.20.0 || >=14" + } + }, "node_modules/zip-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz", @@ -19389,6 +21369,39 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "packages/sdk-typescript/node_modules/@vitest/browser": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@vitest/browser/-/browser-1.6.1.tgz", + "integrity": "sha512-9ZYW6KQ30hJ+rIfJoGH4wAub/KAb4YrFzX0kVLASvTm7nJWVC5EAv5SlzlXVl3h3DaUq5aqHlZl77nmOPnALUQ==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@vitest/utils": "1.6.1", + "magic-string": "^0.30.5", + "sirv": "^2.0.4" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "playwright": "*", + "vitest": "1.6.1", + "webdriverio": "*" + }, + "peerDependenciesMeta": { + "playwright": { + "optional": true + }, + "safaridriver": { + "optional": true + }, + "webdriverio": { + "optional": true + } + } + }, "packages/sdk-typescript/node_modules/@vitest/coverage-v8": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-1.6.1.tgz", @@ -20213,6 +22226,23 @@ "url": "https://opencollective.com/express" } }, + "packages/sdk-typescript/node_modules/sirv": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", + "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">= 10" + } + }, "packages/sdk-typescript/node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -21424,6 +23454,7 @@ "license": "LICENSE", "dependencies": { "@modelcontextprotocol/sdk": "^1.25.1", + "@qwen-code/webui": "*", "cors": "^2.8.5", "express": "^5.1.0", "markdown-it": "^14.1.0", @@ -21725,6 +23756,555 @@ "engines": { "node": ">= 0.6" } + }, + "packages/webui": { + "name": "@qwen-code/webui", + "version": "0.1.0", + "license": "MIT", + "devDependencies": { + "@chromatic-com/storybook": "^5.0.0", + "@storybook/addon-a11y": "^10.1.11", + "@storybook/addon-docs": "^10.1.11", + "@storybook/addon-onboarding": "^10.1.11", + "@storybook/addon-vitest": "^10.1.11", + "@storybook/react-vite": "^10.1.11", + "@types/react": "^18.0.0", + "@types/react-dom": "^18.0.0", + "@vitejs/plugin-react": "^4.2.0", + "@vitest/browser": "^3.2.4", + "@vitest/coverage-v8": "^3.2.4", + "autoprefixer": "^10.4.0", + "eslint-plugin-storybook": "^10.1.11", + "playwright": "^1.57.0", + "postcss": "^8.4.0", + "storybook": "^10.1.11", + "tailwindcss": "^3.4.0", + "typescript": "^5.0.0", + "vite": "^5.0.0", + "vite-plugin-dts": "^3.7.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "packages/webui/node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "packages/webui/node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "packages/webui/node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "packages/webui/node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "packages/webui/node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "packages/webui/node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "packages/webui/node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "packages/webui/node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "packages/webui/node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "packages/webui/node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "packages/webui/node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "packages/webui/node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "packages/webui/node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "packages/webui/node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "packages/webui/node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "packages/webui/node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "packages/webui/node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "packages/webui/node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "packages/webui/node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "packages/webui/node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "packages/webui/node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "packages/webui/node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "packages/webui/node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "packages/webui/node_modules/@types/react": { + "version": "18.3.27", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.27.tgz", + "integrity": "sha512-cisd7gxkzjBKU2GgdYrTdtQx1SORymWyaAFhaxQPK9bYO9ot3Y5OikQRvY0VYQtvwjeQnizCINJAenh/V7MK2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.2.2" + } + }, + "packages/webui/node_modules/@types/react-dom": { + "version": "18.3.7", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", + "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^18.0.0" + } + }, + "packages/webui/node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, + "license": "MIT" + }, + "packages/webui/node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "packages/webui/node_modules/vite": { + "version": "5.4.21", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", + "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } } } } diff --git a/packages/vscode-ide-companion/package.json b/packages/vscode-ide-companion/package.json index 1ed40e136..cb0970fc1 100644 --- a/packages/vscode-ide-companion/package.json +++ b/packages/vscode-ide-companion/package.json @@ -152,7 +152,7 @@ "vitest": "^3.2.4" }, "dependencies": { - "@qwen-code/webui": "workspace:*", + "@qwen-code/webui": "*", "semver": "^7.7.2", "@modelcontextprotocol/sdk": "^1.25.1", "cors": "^2.8.5", diff --git a/packages/webui/.storybook/main.ts b/packages/webui/.storybook/main.ts new file mode 100644 index 000000000..b76cf892f --- /dev/null +++ b/packages/webui/.storybook/main.ts @@ -0,0 +1,25 @@ +import type { StorybookConfig } from '@storybook/react-vite'; + +import { dirname } from 'path'; + +import { fileURLToPath } from 'url'; + +/** + * This function is used to resolve the absolute path of a package. + * It is needed in projects that use Yarn PnP or are set up within a monorepo. + */ +function getAbsolutePath(value: string): string { + return dirname(fileURLToPath(import.meta.resolve(`${value}/package.json`))); +} +const config: StorybookConfig = { + stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'], + addons: [ + getAbsolutePath('@chromatic-com/storybook'), + getAbsolutePath('@storybook/addon-vitest'), + getAbsolutePath('@storybook/addon-a11y'), + getAbsolutePath('@storybook/addon-docs'), + getAbsolutePath('@storybook/addon-onboarding'), + ], + framework: getAbsolutePath('@storybook/react-vite'), +}; +export default config; diff --git a/packages/webui/.storybook/preview.css b/packages/webui/.storybook/preview.css new file mode 100644 index 000000000..ae008a63c --- /dev/null +++ b/packages/webui/.storybook/preview.css @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2025 Qwen Team + * SPDX-License-Identifier: Apache-2.0 + */ + +@tailwind base; +@tailwind components; +@tailwind utilities; + +@import '../src/styles/variables.css'; diff --git a/packages/webui/.storybook/preview.ts b/packages/webui/.storybook/preview.ts new file mode 100644 index 000000000..13dd9ec87 --- /dev/null +++ b/packages/webui/.storybook/preview.ts @@ -0,0 +1,15 @@ +import type { Preview } from '@storybook/react-vite'; +import './preview.css'; + +const preview: Preview = { + parameters: { + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/i, + }, + }, + }, +}; + +export default preview; diff --git a/packages/webui/WEBUI_MIGRATION_PLAN_EN.md b/packages/webui/WEBUI_MIGRATION_PLAN_EN.md new file mode 100644 index 000000000..9e60de1e4 --- /dev/null +++ b/packages/webui/WEBUI_MIGRATION_PLAN_EN.md @@ -0,0 +1,428 @@ +# WebUI Component Library Extraction Plan + +## 1. Background and Goals + +### 1.1 Background + +`packages/vscode-ide-companion` is a VSCode extension whose core content is a WebView page with UI components provided by React. As the product line expands, more scenarios require building products with Web UI: + +- **Chrome Browser Extension** - Sidebar chat interface +- **Web Chat Page** - Pure web application +- **Conversation Share Page** - Render conversations as static HTML + +For excellent software engineering architecture, we need to unify and reuse UI components across products. + +### 1.2 Goals + +1. Extract components from `vscode-ide-companion/src/webview/` into an independent `@qwen-code/webui` package +2. Establish a layered architecture: Pure UI components + Business UI components +3. Use Vite + Storybook for development and component showcase +4. Abstract platform capabilities through Platform Context for cross-platform reuse +5. Provide Tailwind CSS preset to ensure UI consistency across products + +--- + +## 2. Current State Analysis + +### 2.1 Current Code Structure + +`packages/vscode-ide-companion/src/webview/` contains 77 files: + +``` +webview/ +├── App.tsx # Main entry +├── components/ +│ ├── icons/ # 8 icon components +│ ├── layout/ # 8 layout components +│ │ ├── ChatHeader.tsx +│ │ ├── InputForm.tsx +│ │ ├── SessionSelector.tsx +│ │ ├── EmptyState.tsx +│ │ ├── Onboarding.tsx +│ │ └── ... +│ ├── messages/ # Message display components +│ │ ├── UserMessage.tsx +│ │ ├── Assistant/ +│ │ ├── MarkdownRenderer/ +│ │ ├── ThinkingMessage.tsx +│ │ ├── Waiting/ +│ │ └── toolcalls/ # 16 tool call components +│ ├── PermissionDrawer/ # Permission request drawer +│ └── Tooltip.tsx +├── hooks/ # Custom hooks +├── handlers/ # Message handlers +├── styles/ # CSS styles +└── utils/ # Utility functions +``` + +### 2.2 Key Dependency Analysis + +**Platform Coupling Points:** + +- `useVSCode` hook - Calls `acquireVsCodeApi()` for message communication +- `handlers/` - Handles VSCode message protocol +- Some type definitions come from `../types/` directory + +``` +┌─────────────────────────────────────────────────────────┐ +│ App.tsx (Entry) │ +├─────────────────────────────────────────────────────────┤ +│ hooks/ │ handlers/ │ components/ │ +│ ├─useVSCode ◄───┼──────────────────┼──────────────────┤ +│ ├─useSession │ ├─MessageRouter │ ├─icons/ │ +│ ├─useFileContext│ ├─AuthHandler │ ├─layout/ │ +│ └─... │ └─... │ ├─messages/ │ +│ │ │ └─PermDrawer/ │ +├─────────────────────────────────────────────────────────┤ +│ VSCode API (acquireVsCodeApi) │ +└─────────────────────────────────────────────────────────┘ +``` + +--- + +## 3. Target Architecture + +### 3.1 Layered Architecture Design + +``` +┌─────────────────────────────────────────────────────────┐ +│ Layer 3: Platform Adapters │ +│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ +│ │VSCode Adapter│ │Chrome Adapter│ │ Web Adapter │ │ +│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │ +├─────────┼────────────────┼────────────────┼────────────┤ +│ │ │ │ │ +│ ▼ ▼ ▼ │ +│ ┌─────────────────────────────────────────────────┐ │ +│ │ Platform Context Provider │ │ +│ └─────────────────────────────────────────────────┘ │ +├─────────────────────────────────────────────────────────┤ +│ Layer 2: Chat Components │ +│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ +│ │ MessageList│ │ ChatHeader │ │ InputForm │ │ +│ └────────────┘ └────────────┘ └────────────┘ │ +├─────────────────────────────────────────────────────────┤ +│ Layer 1: Primitives (Pure UI) │ +│ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │ +│ │ Button │ │ Input │ │ Icons │ │Tooltip │ │ +│ └────────┘ └────────┘ └────────┘ └────────┘ │ +└─────────────────────────────────────────────────────────┘ +``` + +### 3.2 Platform Context Design + +```typescript +// @qwen-code/webui/src/context/PlatformContext.ts +interface PlatformContext { + // Message communication + postMessage: (message: unknown) => void; + onMessage: (handler: (message: unknown) => void) => () => void; + + // File operations + openFile?: (path: string) => void; + attachFile?: () => void; + + // Authentication + login?: () => void; + + // Platform info + platform: 'vscode' | 'chrome' | 'web' | 'share'; +} +``` + +--- + +## 4. Technical Solution + +### 4.1 Build Configuration (Vite Library Mode) + +**Output formats:** + +- ESM (`dist/index.js`) - Primary format +- CJS (`dist/index.cjs`) - Compatibility +- TypeScript declarations (`dist/index.d.ts`) + +```javascript +// vite.config.ts +export default defineConfig({ + build: { + lib: { + entry: resolve(__dirname, 'src/index.ts'), + formats: ['es', 'cjs'], + fileName: (format) => `index.${format === 'es' ? 'js' : 'cjs'}`, + }, + rollupOptions: { + external: ['react', 'react-dom'], + }, + }, +}); +``` + +### 4.2 Tailwind Preset Solution + +```javascript +// @qwen-code/webui/tailwind.preset.js +module.exports = { + theme: { + extend: { + colors: { + 'app-primary': 'var(--app-primary)', + 'app-background': 'var(--app-primary-background)', + 'app-foreground': 'var(--app-primary-foreground)', + }, + }, + }, +}; + +// Consumer's tailwind.config.js +module.exports = { + presets: [require('@qwen-code/webui/tailwind.preset')], + content: [ + './src/**/*.{ts,tsx}', + './node_modules/@qwen-code/webui/dist/**/*.js', + ], +}; +``` + +### 4.3 Storybook Configuration + +``` +packages/webui/ +├── .storybook/ +│ ├── main.ts # Storybook config +│ ├── preview.ts # Global decorators +│ └── manager.ts # UI config +└── src/ + └── stories/ # Story files +``` + +--- + +## 5. Component Migration Classification + +### 5.1 Batch 1: No-dependency Components (Ready to migrate) + +| Component | Source Path | Complexity | Notes | +| ------------------ | ------------------------ | ---------- | --------------------------- | +| Icons | `components/icons/` | Low | 8 icon components, pure SVG | +| Tooltip | `components/Tooltip.tsx` | Low | Pure UI | +| WaitingMessage | `messages/Waiting/` | Low | Loading state display | +| InterruptedMessage | `messages/Waiting/` | Low | Interrupted state display | + +### 5.2 Batch 2: Light-dependency Components (Need props abstraction) + +| Component | Source Path | Dependency | Refactoring | +| ---------------- | ------------------------------ | ----------- | ---------------- | +| UserMessage | `messages/UserMessage.tsx` | onFileClick | Props injection | +| AssistantMessage | `messages/Assistant/` | onFileClick | Props injection | +| ThinkingMessage | `messages/ThinkingMessage.tsx` | onFileClick | Props injection | +| MarkdownRenderer | `messages/MarkdownRenderer/` | None | Direct migration | +| EmptyState | `layout/EmptyState.tsx` | None | Direct migration | +| ChatHeader | `layout/ChatHeader.tsx` | callbacks | Props injection | + +### 5.3 Batch 3: Medium-dependency Components (Need Context) + +| Component | Source Path | Dependency | Refactoring | +| ------------------- | ---------------------------- | --------------------- | ----------------- | +| InputForm | `layout/InputForm.tsx` | Multiple callbacks | Context + Props | +| SessionSelector | `layout/SessionSelector.tsx` | session data | Props injection | +| CompletionMenu | `layout/CompletionMenu.tsx` | items data | Props injection | +| PermissionDrawer | `PermissionDrawer/` | callbacks | Context + Props | +| ToolCall components | `messages/toolcalls/` | Various tool displays | Modular migration | + +### 5.4 Batch 4: Heavy-dependency (Keep in platform package) + +| Component/Module | Notes | +| ---------------- | ------------------------------------------------- | +| App.tsx | Main entry, contains business orchestration logic | +| hooks/ | Most require platform adaptation | +| handlers/ | VSCode message handling | +| Onboarding | Authentication related, platform-specific | + +--- + +## 6. Incremental Migration Strategy + +### 6.1 Migration Principles + +1. **Bidirectional compatibility**: During migration, vscode-ide-companion can import from both webui and local +2. **One-by-one replacement**: For each migrated component, replace import path in VSCode extension and verify +3. **No breaking changes**: Ensure the extension builds and runs normally after each migration + +### 6.2 Migration Workflow + +``` +Developer ──► @qwen-code/webui ──► vscode-ide-companion + │ │ │ + │ 1. Copy component to webui │ + │ 2. Add Story for verification │ + │ 3. Export from index.ts │ + │ │ │ + │ └──────────────────────┤ + │ │ + │ 4. Update import path + │ 5. Delete original component + │ 6. Build and test +``` + +### 6.3 Example: Migrating Icons + +```typescript +// Before: vscode-ide-companion/src/webview/components/icons/index.ts +export { FileIcon } from './FileIcons.js'; + +// After: Update import +import { FileIcon } from '@qwen-code/webui'; +// or import { FileIcon } from '@qwen-code/webui/icons'; +``` + +--- + +## 7. Task Breakdown + +### Phase 0: Infrastructure Setup (Prerequisites) + +- [ ] **T0-1**: Vite build configuration +- [ ] **T0-2**: Storybook configuration +- [ ] **T0-3**: Tailwind preset creation +- [ ] **T0-4**: Platform Context definition +- [ ] **T0-5**: Shared types migration + +### Phase 1: Pure UI Components Migration + +- [ ] **T1-1**: Icons components migration (8 files) +- [ ] **T1-2**: Tooltip component migration +- [ ] **T1-3**: WaitingMessage / InterruptedMessage migration +- [ ] **T1-4**: Basic Button/Input components refinement + +### Phase 2: Message Components Migration + +- [ ] **T2-1**: MarkdownRenderer migration +- [ ] **T2-2**: UserMessage migration +- [ ] **T2-3**: AssistantMessage migration +- [ ] **T2-4**: ThinkingMessage migration + +### Phase 3: Layout Components Migration + +- [ ] **T3-1**: ChatHeader migration +- [ ] **T3-2**: EmptyState migration +- [ ] **T3-3**: InputForm migration (requires Context) +- [ ] **T3-4**: SessionSelector migration +- [ ] **T3-5**: CompletionMenu migration + +### Phase 4: Complex Components Migration + +- [ ] **T4-1**: PermissionDrawer migration +- [ ] **T4-2**: ToolCall series components migration (16 files) + +### Phase 5: Platform Adapters + +- [ ] **T5-1**: VSCode Adapter implementation +- [ ] **T5-2**: Chrome Extension Adapter +- [ ] **T5-3**: Web/Share Page Adapter + +--- + +## 8. Risks and Considerations + +### 8.1 Common Pitfalls + +1. **Tailwind Class Name Tree Shaking** + - Problem: Tailwind class names may be removed after library bundling + - Solution: Consumer's `content` config needs to include `node_modules/@qwen-code/webui` + +2. **CSS Variable Scope** + - Problem: Variables like `var(--app-primary)` need to be defined by consumers + - Solution: Provide default CSS variables file, or define fallbacks in Tailwind preset + +3. **React Version Compatibility** + - Current vscode-ide-companion uses React 19, webui's peerDependencies is React 18 + - Need to update peerDependencies to `"react": "^18.0.0 || ^19.0.0"` + +4. **ESM/CJS Compatibility** + - VSCode extensions may require CJS format + - Vite needs to be configured for dual format output + +### 8.2 Industry References + +- **Radix UI**: Pure Headless components, styles completely controlled by consumers +- **shadcn/ui**: Copy components into project, rather than importing as dependency +- **Ant Design**: Complete component library, customization through ConfigProvider + +### 8.3 Acceptance Criteria + +Each migration task completion requires: + +1. Component has corresponding Storybook Story +2. Import in vscode-ide-companion has been updated +3. Extension builds successfully (`npm run build:vscode`) +4. Extension functionality works (manual testing or existing tests pass) + +--- + +## 9. Time Estimation + +| Phase | Tasks | Estimated Days | Parallelizable | +| ------- | ----- | -------------- | -------------- | +| Phase 0 | 5 | 2-3 days | Partially | +| Phase 1 | 4 | 1-2 days | Fully | +| Phase 2 | 4 | 2-3 days | Fully | +| Phase 3 | 5 | 3-4 days | Partially | +| Phase 4 | 2 | 3-4 days | Yes | +| Phase 5 | 3 | 2-3 days | Yes | + +**Total**: Approximately 13-19 person-days (sequential execution), can be reduced to 1-2 weeks with parallel work + +--- + +## 10. Development and Debugging Workflow + +### 10.1 Component Development Flow + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ Development Workflow │ +├─────────────────────────────────────────────────────────────────┤ +│ │ +│ 1. Develop/Modify Component │ +│ └── Edit files in @qwen-code/webui/src/ │ +│ │ +│ 2. Debug with Storybook │ +│ └── npm run storybook (port 6006) │ +│ └── View component in isolation │ +│ └── Test different props/states │ +│ │ +│ 3. Build Library │ +│ └── npm run build │ +│ └── Outputs: dist/index.js, dist/index.cjs, dist/index.d.ts │ +│ │ +│ 4. Use in VSCode Extension │ +│ └── import { Component } from '@qwen-code/webui' │ +│ └── No UI code modifications in vscode-ide-companion │ +│ │ +└─────────────────────────────────────────────────────────────────┘ +``` + +### 10.2 Debugging Commands + +```bash +# Start Storybook for component development +cd packages/webui +npm run storybook + +# Watch mode for library development +npm run dev + +# Build library for production +npm run build + +# Type checking +npm run typecheck +``` + +### 10.3 Key Principles + +1. **Single Source of Truth**: All UI components live in `@qwen-code/webui` +2. **Storybook First**: Debug and validate components in Storybook before integration +3. **No UI Code in Consumers**: `vscode-ide-companion` only imports and uses components +4. **Platform Abstraction**: Use `PlatformContext` for platform-specific behaviors diff --git a/packages/webui/WEBUI_MIGRATION_PLAN_ZH.md b/packages/webui/WEBUI_MIGRATION_PLAN_ZH.md new file mode 100644 index 000000000..1e46a3998 --- /dev/null +++ b/packages/webui/WEBUI_MIGRATION_PLAN_ZH.md @@ -0,0 +1,428 @@ +# WebUI 组件库抽离计划 + +## 一、背景与目标 + +### 1.1 背景 + +`packages/vscode-ide-companion` 是一个 VSCode 插件,其核心内容是一个 WebView 页面,大量 UI 部分由 React 组件提供。随着产品线扩展,越来越多的场景需要构建包含 Web UI 的产品: + +- **Chrome 浏览器扩展** - 侧边栏聊天界面 +- **Web 端聊天页面** - 纯 Web 应用 +- **对话分享页面** - 将对话渲染为静态 HTML + +对于优秀的软件工程架构,我们需要让 UI 做到统一且可复用。 + +### 1.2 目标 + +1. 将 `vscode-ide-companion/src/webview/` 中的组件抽离到独立的 `@qwen-code/webui` 包 +2. 建立分层架构:纯 UI 组件 + 业务 UI 组件 +3. 使用 Vite + Storybook 进行开发和组件展示 +4. 通过 Platform Context 抽象平台能力,实现跨平台复用 +5. 提供 Tailwind CSS 预设,保证多产品 UI 一致性 + +--- + +## 二、现状分析 + +### 2.1 当前代码结构 + +`packages/vscode-ide-companion/src/webview/` 包含 77 个文件: + +``` +webview/ +├── App.tsx # 主入口 +├── components/ +│ ├── icons/ # 8 个图标组件 +│ ├── layout/ # 8 个布局组件 +│ │ ├── ChatHeader.tsx +│ │ ├── InputForm.tsx +│ │ ├── SessionSelector.tsx +│ │ ├── EmptyState.tsx +│ │ ├── Onboarding.tsx +│ │ └── ... +│ ├── messages/ # 消息展示组件 +│ │ ├── UserMessage.tsx +│ │ ├── Assistant/ +│ │ ├── MarkdownRenderer/ +│ │ ├── ThinkingMessage.tsx +│ │ ├── Waiting/ +│ │ └── toolcalls/ # 16 个工具调用组件 +│ ├── PermissionDrawer/ # 权限请求抽屉 +│ └── Tooltip.tsx +├── hooks/ # 自定义 hooks +├── handlers/ # 消息处理器 +├── styles/ # CSS 样式 +└── utils/ # 工具函数 +``` + +### 2.2 关键依赖分析 + +**平台耦合点:** + +- `useVSCode` hook - 调用 `acquireVsCodeApi()` 进行消息通信 +- `handlers/` - 处理 VSCode 消息协议 +- 部分类型定义来自 `../types/` 目录 + +``` +┌─────────────────────────────────────────────────────────┐ +│ App.tsx (入口) │ +├─────────────────────────────────────────────────────────┤ +│ hooks/ │ handlers/ │ components/ │ +│ ├─useVSCode ◄───┼──────────────────┼──────────────────┤ +│ ├─useSession │ ├─MessageRouter │ ├─icons/ │ +│ ├─useFileContext│ ├─AuthHandler │ ├─layout/ │ +│ └─... │ └─... │ ├─messages/ │ +│ │ │ └─PermDrawer/ │ +├─────────────────────────────────────────────────────────┤ +│ VSCode API (acquireVsCodeApi) │ +└─────────────────────────────────────────────────────────┘ +``` + +--- + +## 三、目标架构 + +### 3.1 分层架构设计 + +``` +┌─────────────────────────────────────────────────────────┐ +│ Layer 3: Platform Adapters │ +│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ +│ │VSCode Adapter│ │Chrome Adapter│ │ Web Adapter │ │ +│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │ +├─────────┼────────────────┼────────────────┼────────────┤ +│ │ │ │ │ +│ ▼ ▼ ▼ │ +│ ┌─────────────────────────────────────────────────┐ │ +│ │ Platform Context Provider │ │ +│ └─────────────────────────────────────────────────┘ │ +├─────────────────────────────────────────────────────────┤ +│ Layer 2: Chat Components │ +│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ +│ │ MessageList│ │ ChatHeader │ │ InputForm │ │ +│ └────────────┘ └────────────┘ └────────────┘ │ +├─────────────────────────────────────────────────────────┤ +│ Layer 1: Primitives (纯 UI) │ +│ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │ +│ │ Button │ │ Input │ │ Icons │ │Tooltip │ │ +│ └────────┘ └────────┘ └────────┘ └────────┘ │ +└─────────────────────────────────────────────────────────┘ +``` + +### 3.2 Platform Context 设计 + +```typescript +// @qwen-code/webui/src/context/PlatformContext.ts +interface PlatformContext { + // 消息通信 + postMessage: (message: unknown) => void; + onMessage: (handler: (message: unknown) => void) => () => void; + + // 文件操作 + openFile?: (path: string) => void; + attachFile?: () => void; + + // 认证 + login?: () => void; + + // 平台信息 + platform: 'vscode' | 'chrome' | 'web' | 'share'; +} +``` + +--- + +## 四、技术方案 + +### 4.1 构建配置(Vite Library Mode) + +**输出格式:** + +- ESM (`dist/index.js`) - 主要格式 +- CJS (`dist/index.cjs`) - 兼容性 +- TypeScript 声明 (`dist/index.d.ts`) + +```javascript +// vite.config.ts +export default defineConfig({ + build: { + lib: { + entry: resolve(__dirname, 'src/index.ts'), + formats: ['es', 'cjs'], + fileName: (format) => `index.${format === 'es' ? 'js' : 'cjs'}`, + }, + rollupOptions: { + external: ['react', 'react-dom'], + }, + }, +}); +``` + +### 4.2 Tailwind 预设方案 + +```javascript +// @qwen-code/webui/tailwind.preset.js +module.exports = { + theme: { + extend: { + colors: { + 'app-primary': 'var(--app-primary)', + 'app-background': 'var(--app-primary-background)', + 'app-foreground': 'var(--app-primary-foreground)', + }, + }, + }, +}; + +// 消费方 tailwind.config.js +module.exports = { + presets: [require('@qwen-code/webui/tailwind.preset')], + content: [ + './src/**/*.{ts,tsx}', + './node_modules/@qwen-code/webui/dist/**/*.js', + ], +}; +``` + +### 4.3 Storybook 配置 + +``` +packages/webui/ +├── .storybook/ +│ ├── main.ts # Storybook 配置 +│ ├── preview.ts # 全局装饰器 +│ └── manager.ts # UI 配置 +└── src/ + └── stories/ # Story 文件 +``` + +--- + +## 五、组件迁移分类 + +### 5.1 第一批:无依赖组件(可立即迁移) + +| 组件 | 来源路径 | 复杂度 | 说明 | +| ------------------ | ------------------------ | ------ | -------------------- | +| Icons | `components/icons/` | 低 | 8 个图标组件,纯 SVG | +| Tooltip | `components/Tooltip.tsx` | 低 | 纯 UI | +| WaitingMessage | `messages/Waiting/` | 低 | 加载状态展示 | +| InterruptedMessage | `messages/Waiting/` | 低 | 中断状态展示 | + +### 5.2 第二批:轻度依赖组件(需要抽象 props) + +| 组件 | 来源路径 | 依赖 | 改造方式 | +| ---------------- | ------------------------------ | ----------- | --------------- | +| UserMessage | `messages/UserMessage.tsx` | onFileClick | 通过 props 注入 | +| AssistantMessage | `messages/Assistant/` | onFileClick | 通过 props 注入 | +| ThinkingMessage | `messages/ThinkingMessage.tsx` | onFileClick | 通过 props 注入 | +| MarkdownRenderer | `messages/MarkdownRenderer/` | 无 | 直接迁移 | +| EmptyState | `layout/EmptyState.tsx` | 无 | 直接迁移 | +| ChatHeader | `layout/ChatHeader.tsx` | callbacks | 通过 props 注入 | + +### 5.3 第三批:中度依赖组件(需要 Context) + +| 组件 | 来源路径 | 依赖 | 改造方式 | +| ---------------- | ---------------------------- | -------------- | --------------- | +| InputForm | `layout/InputForm.tsx` | 多个 callbacks | Context + Props | +| SessionSelector | `layout/SessionSelector.tsx` | session 数据 | Props 注入 | +| CompletionMenu | `layout/CompletionMenu.tsx` | items 数据 | Props 注入 | +| PermissionDrawer | `PermissionDrawer/` | 回调函数 | Context + Props | +| ToolCall 组件 | `messages/toolcalls/` | 多种工具展示 | 分模块迁移 | + +### 5.4 第四批:重度依赖(保留在平台包) + +| 组件/模块 | 说明 | +| ---------- | ------------------------ | +| App.tsx | 总入口,包含业务编排逻辑 | +| hooks/ | 大部分需要平台适配 | +| handlers/ | VSCode 消息处理 | +| Onboarding | 认证相关,平台特定 | + +--- + +## 六、渐进式迁移策略 + +### 6.1 迁移原则 + +1. **双向兼容**:迁移期间,vscode-ide-companion 可以同时从 webui 和本地导入 +2. **逐个替换**:每迁移一个组件,在 VSCode 插件中替换导入路径并验证 +3. **不破坏现有功能**:确保每次迁移后插件可正常构建和运行 + +### 6.2 迁移流程 + +``` +开发者 ──► @qwen-code/webui ──► vscode-ide-companion + │ │ │ + │ 1. 复制组件到 webui │ + │ 2. 添加 Story 验证 │ + │ 3. 从 index.ts 导出 │ + │ │ │ + │ └──────────────────────┤ + │ │ + │ 4. 更新 import 路径 + │ 5. 删除原组件文件 + │ 6. 构建测试验证 +``` + +### 6.3 示例:迁移 Icons + +```typescript +// Before: vscode-ide-companion/src/webview/components/icons/index.ts +export { FileIcon } from './FileIcons.js'; + +// After: 修改导入 +import { FileIcon } from '@qwen-code/webui'; +// 或 import { FileIcon } from '@qwen-code/webui/icons'; +``` + +--- + +## 七、任务拆分 + +### Phase 0: 基础设施搭建(前置任务) + +- [ ] **T0-1**: Vite 构建配置 +- [ ] **T0-2**: Storybook 配置 +- [ ] **T0-3**: Tailwind 预设创建 +- [ ] **T0-4**: Platform Context 定义 +- [ ] **T0-5**: 类型定义迁移(共享 types) + +### Phase 1: 纯 UI 组件迁移 + +- [ ] **T1-1**: Icons 组件迁移(8 个文件) +- [ ] **T1-2**: Tooltip 组件迁移 +- [ ] **T1-3**: WaitingMessage / InterruptedMessage 迁移 +- [ ] **T1-4**: 基础 Button/Input 组件完善 + +### Phase 2: 消息组件迁移 + +- [ ] **T2-1**: MarkdownRenderer 迁移 +- [ ] **T2-2**: UserMessage 迁移 +- [ ] **T2-3**: AssistantMessage 迁移 +- [ ] **T2-4**: ThinkingMessage 迁移 + +### Phase 3: 布局组件迁移 + +- [ ] **T3-1**: ChatHeader 迁移 +- [ ] **T3-2**: EmptyState 迁移 +- [ ] **T3-3**: InputForm 迁移(需要 Context) +- [ ] **T3-4**: SessionSelector 迁移 +- [ ] **T3-5**: CompletionMenu 迁移 + +### Phase 4: 复杂组件迁移 + +- [ ] **T4-1**: PermissionDrawer 迁移 +- [ ] **T4-2**: ToolCall 系列组件迁移(16 个文件) + +### Phase 5: 平台适配器 + +- [ ] **T5-1**: VSCode Adapter 实现 +- [ ] **T5-2**: Chrome Extension Adapter +- [ ] **T5-3**: Web/Share Page Adapter + +--- + +## 八、风险与注意事项 + +### 8.1 常见坑点 + +1. **Tailwind 类名 Tree Shaking** + - 问题:组件库打包后 Tailwind 类名可能被移除 + - 解决:消费方的 `content` 配置需要包含 `node_modules/@qwen-code/webui` + +2. **CSS 变量作用域** + - 问题:`var(--app-primary)` 等变量需要在消费方定义 + - 解决:提供默认 CSS 变量文件,或在 Tailwind 预设中定义 fallback + +3. **React 版本兼容** + - 当前 vscode-ide-companion 使用 React 19,webui 的 peerDependencies 是 React 18 + - 需要更新 peerDependencies 为 `"react": "^18.0.0 || ^19.0.0"` + +4. **ESM/CJS 兼容** + - VSCode 扩展可能需要 CJS 格式 + - Vite 需要配置双格式输出 + +### 8.2 业界参考 + +- **Radix UI**: 纯 Headless 组件,样式完全由消费方控制 +- **shadcn/ui**: 复制组件到项目中,而非作为依赖引入 +- **Ant Design**: 完整的组件库,通过 ConfigProvider 进行定制 + +### 8.3 验收标准 + +每个迁移任务完成后需要: + +1. 组件有对应的 Storybook Story +2. vscode-ide-companion 中的导入已更新 +3. 插件可正常构建 (`npm run build:vscode`) +4. 插件功能正常(手动测试或已有测试通过) + +--- + +## 九、预估时间 + +| 阶段 | 任务数 | 预估人天 | 可并行 | +| ------- | ------ | -------- | ---------- | +| Phase 0 | 5 | 2-3 天 | 部分可并行 | +| Phase 1 | 4 | 1-2 天 | 全部可并行 | +| Phase 2 | 4 | 2-3 天 | 全部可并行 | +| Phase 3 | 5 | 3-4 天 | 部分可并行 | +| Phase 4 | 2 | 3-4 天 | 可并行 | +| Phase 5 | 3 | 2-3 天 | 可并行 | + +**总计**:约 13-19 人天(单人顺序执行),如果多人并行可缩短至 1-2 周 + +--- + +## 十、开发与调试流程 + +### 10.1 组件开发流程 + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ 开发工作流程 │ +├─────────────────────────────────────────────────────────────────┤ +│ │ +│ 1. 开发/修改组件 │ +│ └── 在 @qwen-code/webui/src/ 中编辑文件 │ +│ │ +│ 2. 使用 Storybook 调试 │ +│ └── npm run storybook (端口 6006) │ +│ └── 独立查看组件 │ +│ └── 测试不同的 props/状态 │ +│ │ +│ 3. 构建组件库 │ +│ └── npm run build │ +│ └── 输出: dist/index.js, dist/index.cjs, dist/index.d.ts │ +│ │ +│ 4. 在 VSCode 插件中使用 │ +│ └── import { Component } from '@qwen-code/webui' │ +│ └── vscode-ide-companion 中不再修改 UI 代码 │ +│ │ +└─────────────────────────────────────────────────────────────────┘ +``` + +### 10.2 调试命令 + +```bash +# 启动 Storybook 进行组件开发 +cd packages/webui +npm run storybook + +# 监听模式进行库开发 +npm run dev + +# 构建生产版本 +npm run build + +# 类型检查 +npm run typecheck +``` + +### 10.3 核心原则 + +1. **单一数据源**: 所有 UI 组件都在 `@qwen-code/webui` 中 +2. **Storybook 优先**: 在集成前先在 Storybook 中调试和验证组件 +3. **消费方不修改 UI 代码**: `vscode-ide-companion` 只导入和使用组件 +4. **平台抽象**: 使用 `PlatformContext` 处理平台特定行为 diff --git a/packages/webui/package.json b/packages/webui/package.json index 757a6d812..ffd2b956d 100644 --- a/packages/webui/package.json +++ b/packages/webui/package.json @@ -2,28 +2,60 @@ "name": "@qwen-code/webui", "version": "0.1.0", "description": "Shared UI components for Qwen Code packages", - "main": "dist/index.js", - "module": "dist/index.esm.js", - "types": "dist/index.d.ts", "type": "module", + "main": "./dist/index.cjs", + "module": "./dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js", + "require": "./dist/index.cjs" + }, + "./tailwind.preset": "./tailwind.preset.cjs", + "./styles.css": "./dist/styles.css" + }, + "files": [ + "dist", + "tailwind.preset.cjs" + ], + "sideEffects": [ + "**/*.css" + ], "scripts": { - "build": "tsc && rollup -c", - "dev": "tsc --watch", + "dev": "vite build --watch", + "build": "vite build", + "typecheck": "tsc --noEmit", "lint": "eslint src --ext .ts,.tsx", "lint:fix": "eslint src --ext .ts,.tsx --fix", - "typecheck": "tsc --noEmit" + "storybook": "storybook dev -p 6006", + "build-storybook": "storybook build" }, "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" }, "devDependencies": { "@types/react": "^18.0.0", "@types/react-dom": "^18.0.0", + "@vitejs/plugin-react": "^4.2.0", + "autoprefixer": "^10.4.0", + "postcss": "^8.4.0", + "tailwindcss": "^3.4.0", "typescript": "^5.0.0", - "@rollup/plugin-typescript": "^11.0.0", - "rollup": "^4.0.0", - "rollup-plugin-dts": "^6.0.0" + "vite": "^5.0.0", + "vite-plugin-dts": "^3.7.0", + "storybook": "^10.1.11", + "@storybook/react-vite": "^10.1.11", + "@chromatic-com/storybook": "^5.0.0", + "@storybook/addon-vitest": "^10.1.11", + "@storybook/addon-a11y": "^10.1.11", + "@storybook/addon-docs": "^10.1.11", + "@storybook/addon-onboarding": "^10.1.11", + "eslint-plugin-storybook": "^10.1.11", + "playwright": "^1.57.0", + "@vitest/browser": "^3.2.4", + "@vitest/coverage-v8": "^3.2.4" }, "keywords": [ "qwen", diff --git a/packages/webui/postcss.config.cjs b/packages/webui/postcss.config.cjs new file mode 100644 index 000000000..29fd6d75d --- /dev/null +++ b/packages/webui/postcss.config.cjs @@ -0,0 +1,13 @@ +/** + * @license + * Copyright 2025 Qwen Team + * SPDX-License-Identifier: Apache-2.0 + */ + +/* eslint-env node */ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +}; diff --git a/packages/webui/rollup.config.js b/packages/webui/rollup.config.js deleted file mode 100644 index c6340858a..000000000 --- a/packages/webui/rollup.config.js +++ /dev/null @@ -1,47 +0,0 @@ -import typescript from '@rollup/plugin-typescript'; -import { dts } from 'rollup-plugin-dts'; -import pkg from './package.json' with { type: 'json' }; - -const name = pkg.name; - -export default [ - // Browser-friendly version - { - input: 'src/index.ts', - output: { - name, - file: 'dist/index.min.js', - format: 'iife', - globals: { - react: 'React', - 'react-dom': 'ReactDOM', - }, - }, - external: ['react', 'react-dom'], - plugins: [ - typescript({ - tsconfig: './tsconfig.json', - }), - ], - }, - // ES module version - { - input: 'src/index.ts', - output: [ - { file: 'dist/index.esm.js', format: 'es' }, - { file: 'dist/index.cjs.js', format: 'cjs' }, - ], - external: ['react', 'react-dom'], - plugins: [ - typescript({ - tsconfig: './tsconfig.json', - }), - ], - }, - // Type declarations - { - input: 'dist/dts/src/index.d.ts', - output: [{ file: 'dist/index.d.ts', format: 'es' }], - plugins: [dts()], - }, -]; diff --git a/packages/webui/src/components/ui/Button.stories.tsx b/packages/webui/src/components/ui/Button.stories.tsx new file mode 100644 index 000000000..68724cd84 --- /dev/null +++ b/packages/webui/src/components/ui/Button.stories.tsx @@ -0,0 +1,83 @@ +/** + * @license + * Copyright 2025 Qwen Team + * SPDX-License-Identifier: Apache-2.0 + */ + +import type { Meta, StoryObj } from '@storybook/react-vite'; +import Button from './Button'; + +/** + * Button component for user interactions. + * Supports multiple variants and sizes. + */ +const meta: Meta = { + title: 'UI/Button', + component: Button, + parameters: { + layout: 'centered', + }, + tags: ['autodocs'], + argTypes: { + variant: { + control: 'select', + options: ['primary', 'secondary', 'danger'], + description: 'Visual style variant', + }, + size: { + control: 'select', + options: ['sm', 'md', 'lg'], + description: 'Button size', + }, + disabled: { + control: 'boolean', + description: 'Disabled state', + }, + onClick: { action: 'clicked' }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Primary: Story = { + args: { + children: 'Primary Button', + variant: 'primary', + }, +}; + +export const Secondary: Story = { + args: { + children: 'Secondary Button', + variant: 'secondary', + }, +}; + +export const Danger: Story = { + args: { + children: 'Danger Button', + variant: 'danger', + }, +}; + +export const Small: Story = { + args: { + children: 'Small Button', + size: 'sm', + }, +}; + +export const Large: Story = { + args: { + children: 'Large Button', + size: 'lg', + }, +}; + +export const Disabled: Story = { + args: { + children: 'Disabled Button', + disabled: true, + }, +}; diff --git a/packages/webui/src/components/ui/Tooltip.stories.tsx b/packages/webui/src/components/ui/Tooltip.stories.tsx new file mode 100644 index 000000000..6ba656ad5 --- /dev/null +++ b/packages/webui/src/components/ui/Tooltip.stories.tsx @@ -0,0 +1,68 @@ +/** + * @license + * Copyright 2025 Qwen Team + * SPDX-License-Identifier: Apache-2.0 + */ + +import type { Meta, StoryObj } from '@storybook/react-vite'; +import Tooltip from './Tooltip'; +import Button from './Button'; + +/** + * Tooltip component for displaying contextual information on hover. + * Supports four positions: top, right, bottom, left. + */ +const meta: Meta = { + title: 'UI/Tooltip', + component: Tooltip, + parameters: { + layout: 'centered', + }, + tags: ['autodocs'], + argTypes: { + position: { + control: 'select', + options: ['top', 'right', 'bottom', 'left'], + description: 'Tooltip position relative to trigger', + }, + content: { + control: 'text', + description: 'Tooltip content text', + }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Top: Story = { + args: { + content: 'Tooltip on top', + position: 'top', + children: , + }, +}; + +export const Right: Story = { + args: { + content: 'Tooltip on right', + position: 'right', + children: , + }, +}; + +export const Bottom: Story = { + args: { + content: 'Tooltip on bottom', + position: 'bottom', + children: , + }, +}; + +export const Left: Story = { + args: { + content: 'Tooltip on left', + position: 'left', + children: , + }, +}; diff --git a/packages/webui/src/context/PlatformContext.tsx b/packages/webui/src/context/PlatformContext.tsx new file mode 100644 index 000000000..dd244c72b --- /dev/null +++ b/packages/webui/src/context/PlatformContext.tsx @@ -0,0 +1,89 @@ +/** + * @license + * Copyright 2025 Qwen Team + * SPDX-License-Identifier: Apache-2.0 + */ + +import type React from 'react'; +import { createContext, useContext } from 'react'; + +/** + * Platform types supported by the webui library + */ +export type PlatformType = 'vscode' | 'chrome' | 'web' | 'share'; + +/** + * Platform context interface for cross-platform component reuse. + * Each platform adapter implements this interface. + */ +export interface PlatformContextValue { + /** Current platform identifier */ + platform: PlatformType; + + /** Send message to platform host */ + postMessage: (message: unknown) => void; + + /** Subscribe to messages from platform host */ + onMessage: (handler: (message: unknown) => void) => () => void; + + /** Open a file in the platform's editor (optional) */ + openFile?: (path: string) => void; + + /** Trigger file attachment dialog (optional) */ + attachFile?: () => void; + + /** Trigger platform login flow (optional) */ + login?: () => void; + + /** Copy text to clipboard */ + copyToClipboard?: (text: string) => Promise; + + /** Platform-specific feature flags */ + features?: { + canOpenFile?: boolean; + canAttachFile?: boolean; + canLogin?: boolean; + canCopy?: boolean; + }; +} + +/** + * Default noop implementation for platforms without message support + */ +const defaultContext: PlatformContextValue = { + platform: 'web', + postMessage: () => {}, + onMessage: () => () => {}, +}; + +/** + * Platform context for accessing platform-specific capabilities + */ +export const PlatformContext = + createContext(defaultContext); + +/** + * Hook to access platform context + */ +export function usePlatform(): PlatformContextValue { + return useContext(PlatformContext); +} + +/** + * Provider component props + */ +export interface PlatformProviderProps { + children: React.ReactNode; + value: PlatformContextValue; +} + +/** + * Platform context provider component + */ +export function PlatformProvider({ children, value }: PlatformProviderProps) { + return ( + + {children} + + ); +} diff --git a/packages/webui/src/index.ts b/packages/webui/src/index.ts index 6f4066229..4be114226 100644 --- a/packages/webui/src/index.ts +++ b/packages/webui/src/index.ts @@ -1,6 +1,18 @@ // Shared UI Components Export // Export all shared components from this package +// Context +export { + PlatformContext, + PlatformProvider, + usePlatform, +} from './context/PlatformContext'; +export type { + PlatformContextValue, + PlatformProviderProps, + PlatformType, +} from './context/PlatformContext'; + // Layout components export { default as Container } from './components/layout/Container'; export { default as Header } from './components/layout/Header'; @@ -33,3 +45,10 @@ export { useLocalStorage } from './hooks/useLocalStorage'; // Types export type { Theme } from './types/theme'; export type { MessageProps } from './types/messages'; +export type { ChatMessage, MessageRole, PlanEntry } from './types/chat'; +export type { + ToolCallStatus, + ToolCallLocation, + ToolCallContentItem, + ToolCallUpdate, +} from './types/toolCall'; diff --git a/packages/webui/src/styles/variables.css b/packages/webui/src/styles/variables.css new file mode 100644 index 000000000..8ec989554 --- /dev/null +++ b/packages/webui/src/styles/variables.css @@ -0,0 +1,52 @@ +/** + * @license + * Copyright 2025 Qwen Team + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * Default CSS variables for @qwen-code/webui + * Consumers can override these variables to customize the theme. + */ +:root { + /* Primary colors */ + --app-primary: #3b82f6; + --app-primary-hover: #2563eb; + --app-primary-foreground: #ffffff; + + /* Background colors */ + --app-background: #ffffff; + --app-background-secondary: #f3f4f6; + --app-background-tertiary: #e5e7eb; + + /* Foreground/text colors */ + --app-foreground: #111827; + --app-foreground-secondary: #6b7280; + --app-foreground-muted: #9ca3af; + + /* Border colors */ + --app-border: #e5e7eb; + --app-border-focus: #3b82f6; + + /* Status colors */ + --app-success: #10b981; + --app-warning: #f59e0b; + --app-error: #ef4444; + --app-info: #3b82f6; + + /* Typography */ + --app-font-sans: system-ui, -apple-system, sans-serif; + --app-font-mono: ui-monospace, monospace; + + /* Border radius */ + --app-radius-sm: 0.25rem; + --app-radius-md: 0.375rem; + --app-radius-lg: 0.5rem; + + /* Spacing */ + --app-spacing-xs: 0.25rem; + --app-spacing-sm: 0.5rem; + --app-spacing-md: 1rem; + --app-spacing-lg: 1.5rem; + --app-spacing-xl: 2rem; +} diff --git a/packages/webui/src/types/chat.ts b/packages/webui/src/types/chat.ts new file mode 100644 index 000000000..11bd77fc2 --- /dev/null +++ b/packages/webui/src/types/chat.ts @@ -0,0 +1,28 @@ +/** + * @license + * Copyright 2025 Qwen Team + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * Chat message role types + */ +export type MessageRole = 'user' | 'assistant' | 'system'; + +/** + * Basic chat message structure + */ +export interface ChatMessage { + role: MessageRole; + content: string; + timestamp: number; +} + +/** + * Plan entry for task tracking + */ +export interface PlanEntry { + content: string; + priority?: 'high' | 'medium' | 'low'; + status: 'pending' | 'in_progress' | 'completed'; +} diff --git a/packages/webui/src/types/toolCall.ts b/packages/webui/src/types/toolCall.ts new file mode 100644 index 000000000..37762fb8a --- /dev/null +++ b/packages/webui/src/types/toolCall.ts @@ -0,0 +1,48 @@ +/** + * @license + * Copyright 2025 Qwen Team + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * Tool call status + */ +export type ToolCallStatus = 'pending' | 'in_progress' | 'completed' | 'failed'; + +/** + * Tool call location reference + */ +export interface ToolCallLocation { + path: string; + line?: number | null; +} + +/** + * Tool call content item + */ +export interface ToolCallContentItem { + type: 'content' | 'diff'; + content?: { + type: string; + text?: string; + [key: string]: unknown; + }; + path?: string; + oldText?: string | null; + newText?: string; + [key: string]: unknown; +} + +/** + * Tool call update data + */ +export interface ToolCallUpdate { + toolCallId: string; + kind?: string; + title?: string; + status?: ToolCallStatus; + rawInput?: unknown; + content?: ToolCallContentItem[]; + locations?: ToolCallLocation[]; + timestamp?: number; +} diff --git a/packages/webui/tailwind.config.cjs b/packages/webui/tailwind.config.cjs new file mode 100644 index 000000000..58599c59b --- /dev/null +++ b/packages/webui/tailwind.config.cjs @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2025 Qwen Team + * SPDX-License-Identifier: Apache-2.0 + */ + +/* eslint-env node */ +module.exports = { + presets: [require('./tailwind.preset.cjs')], + content: ['./src/**/*.{ts,tsx}'], +}; diff --git a/packages/webui/tailwind.preset.cjs b/packages/webui/tailwind.preset.cjs new file mode 100644 index 000000000..21aa7eca0 --- /dev/null +++ b/packages/webui/tailwind.preset.cjs @@ -0,0 +1,71 @@ +/** + * @license + * Copyright 2025 Qwen Team + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @qwen-code/webui Tailwind CSS Preset + * + * This preset provides shared theme configuration for all Qwen Code products. + * Consumers should include this preset in their tailwind.config.js: + * + * @example + * module.exports = { + * presets: [require('@qwen-code/webui/tailwind.preset')], + * content: [ + * './src/**\/*.{ts,tsx}', + * './node_modules/@qwen-code/webui/dist/**\/*.js' + * ] + * } + */ + +/* eslint-env node */ +module.exports = { + theme: { + extend: { + colors: { + // Primary colors using CSS variables for runtime theming + 'app-primary': 'var(--app-primary, #3b82f6)', + 'app-primary-hover': 'var(--app-primary-hover, #2563eb)', + 'app-primary-foreground': 'var(--app-primary-foreground, #ffffff)', + + // Background colors + 'app-background': 'var(--app-background, #ffffff)', + 'app-background-secondary': 'var(--app-background-secondary, #f3f4f6)', + 'app-background-tertiary': 'var(--app-background-tertiary, #e5e7eb)', + + // Foreground/text colors + 'app-foreground': 'var(--app-foreground, #111827)', + 'app-foreground-secondary': 'var(--app-foreground-secondary, #6b7280)', + 'app-foreground-muted': 'var(--app-foreground-muted, #9ca3af)', + + // Border colors + 'app-border': 'var(--app-border, #e5e7eb)', + 'app-border-focus': 'var(--app-border-focus, #3b82f6)', + + // Status colors + 'app-success': 'var(--app-success, #10b981)', + 'app-warning': 'var(--app-warning, #f59e0b)', + 'app-error': 'var(--app-error, #ef4444)', + 'app-info': 'var(--app-info, #3b82f6)', + }, + fontFamily: { + sans: ['var(--app-font-sans, system-ui, sans-serif)'], + mono: ['var(--app-font-mono, ui-monospace, monospace)'], + }, + borderRadius: { + 'app-sm': 'var(--app-radius-sm, 0.25rem)', + 'app-md': 'var(--app-radius-md, 0.375rem)', + 'app-lg': 'var(--app-radius-lg, 0.5rem)', + }, + spacing: { + 'app-xs': 'var(--app-spacing-xs, 0.25rem)', + 'app-sm': 'var(--app-spacing-sm, 0.5rem)', + 'app-md': 'var(--app-spacing-md, 1rem)', + 'app-lg': 'var(--app-spacing-lg, 1.5rem)', + 'app-xl': 'var(--app-spacing-xl, 2rem)', + }, + }, + }, +}; diff --git a/packages/webui/tsconfig.json b/packages/webui/tsconfig.json index 58209e086..3e0be85f6 100644 --- a/packages/webui/tsconfig.json +++ b/packages/webui/tsconfig.json @@ -14,11 +14,8 @@ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, - "noFallthroughCasesInSwitch": true, - "declaration": true, - "declarationDir": "./dist", - "emitDeclarationOnly": true + "noFallthroughCasesInSwitch": true }, "include": ["src"], - "exclude": ["node_modules", "dist"] + "exclude": ["node_modules", "dist", "**/*.stories.tsx"] } diff --git a/packages/webui/vite.config.ts b/packages/webui/vite.config.ts new file mode 100644 index 000000000..9edb5b28c --- /dev/null +++ b/packages/webui/vite.config.ts @@ -0,0 +1,53 @@ +/** + * @license + * Copyright 2025 Qwen Team + * SPDX-License-Identifier: Apache-2.0 + */ + +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; +import dts from 'vite-plugin-dts'; +import { resolve } from 'path'; + +/** + * Vite configuration for @qwen-code/webui library + * + * Build outputs: + * - ESM: dist/index.js (primary format) + * - CJS: dist/index.cjs (compatibility) + * - TypeScript declarations: dist/index.d.ts + * - CSS: dist/styles.css (optional styles) + */ +export default defineConfig({ + plugins: [ + react(), + dts({ + include: ['src'], + outDir: 'dist', + rollupTypes: true, + insertTypesEntry: true, + }), + ], + build: { + lib: { + entry: resolve(__dirname, 'src/index.ts'), + name: 'QwenCodeWebUI', + formats: ['es', 'cjs'], + fileName: (format) => `index.${format === 'es' ? 'js' : 'cjs'}`, + }, + rollupOptions: { + external: ['react', 'react-dom', 'react/jsx-runtime'], + output: { + globals: { + react: 'React', + 'react-dom': 'ReactDOM', + 'react/jsx-runtime': 'jsxRuntime', + }, + assetFileNames: 'styles.[ext]', + }, + }, + sourcemap: true, + minify: false, + cssCodeSplit: false, + }, +});