diff --git a/.gitignore b/.gitignore index 9cbd5ac40..eeab3f764 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,8 @@ packages/vite/runtime packages/rolldown/src/public/fonts packages/rolldown/src/app/public/fonts packages/rolldown/runtime +packages/oxc/src/public/fonts +packages/oxc/src/app/public/fonts packages/kit/skills .rolldown .devtools-oxc diff --git a/AGENTS.md b/AGENTS.md index 50384e774..27fe06c7f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -23,7 +23,7 @@ Monorepo (`pnpm` workspaces + `turbo`). ESM TypeScript; bundled with `tsdown`. P | `packages/ui` | `@vitejs/devtools-ui` | Shared UI components, composables, and UnoCSS preset (`presetDevToolsUI`). Private, not published. | | `packages/rolldown` | `@vitejs/devtools-rolldown` | Nuxt UI for Rolldown build data. Hub-mounted via `Plugin.devtools.setup`. Serves at `/__devtools-rolldown/`. | | `packages/vite` | `@vitejs/devtools-vite` | Nuxt UI for Vite DevTools (WIP). Hub-mounted via `Plugin.devtools.setup`. Serves at `/__devtools-vite/`. | -| `packages/oxc` | `@vitejs/devtools-oxc` | Oxc toolchain (oxlint/oxfmt) inspector, donated from [`yuyinws/oxc-inspector`](https://github.com/yuyinws/oxc-inspector) with full history; owned by Leo. Advertised by core as a built-in install launcher in the `~viteplus` group (installed on demand), mounted via `DevToolsOxc()` from `@vitejs/devtools-oxc/vite` once present, plus a standalone CLI/client. A workspace member on the current devframe/hub APIs; its build is not wired into turbo yet (the `@nuxt/ui` client is pending a UI-stack decision), so it stays out of the build/typecheck/lint/export-snapshot gates. | +| `packages/oxc` | `@vitejs/devtools-oxc` | Oxc toolchain (oxlint/oxfmt) inspector, donated from [`yuyinws/oxc-inspector`](https://github.com/yuyinws/oxc-inspector) with full history; owned by Leo. Advertised by core as a built-in install launcher in the `~viteplus` group (installed on demand), mounted via `DevToolsOxc()` from `@vitejs/devtools-oxc/vite` once present, plus a standalone CLI/client. Its Nuxt client is on the shared stack — UnoCSS via `presetDevToolsUI` and `@vitejs/devtools-ui` components (an oxc-cyan `primary` scale derived from the `BannerOxcDevTools` accent) — and is wired into the turbo build, `vue-tsc` typecheck (own `src/tsconfig.json` reference) and export-snapshot gates. It dogfoods its own oxlint/oxfmt on itself (run `pnpm -C packages/oxc lint`), whose formatting conflicts with the repo-wide antfu ESLint config, so it stays out of the shared ESLint run. | | `packages/vitest` | `@vitejs/devtools-vitest` | Slim launcher for the Vitest UI, in the `~viteplus` dock group. A `launcher` dock (only shown when the project uses Vitest) installs `@vitest/ui` on demand, spawns `vitest --ui`, then swaps to an iframe. Serves its favicon at `/__devtools-vitest/`. | | `packages/webext` | — | Browser extension scaffolding (ancillary). | diff --git a/eslint.config.js b/eslint.config.js index 506b2c9ca..5ac10fcf2 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -14,9 +14,10 @@ export default antfu({ // dependency specifiers rather than the repo catalog and stays out of the // repo-wide ESLint run. 'playgrounds/production', - // `packages/oxc` (donated from yuyinws/oxc-inspector) carries its own - // oxlint/oxfmt style and is linted by its own toolchain, so it stays out of - // the repo-wide ESLint run. + // `packages/oxc` is DevTools for the Oxc toolchain and dogfoods its own + // oxlint/oxfmt on itself, whose formatting (e.g. `arrowParens: "avoid"`) + // conflicts with this shared antfu config, so it is linted by its own + // toolchain (`pnpm -C packages/oxc lint`) rather than the repo-wide run. 'packages/oxc', '!packages/oxc/package.json', ], diff --git a/packages/oxc/package.json b/packages/oxc/package.json index 633953eff..3f470bf03 100644 --- a/packages/oxc/package.json +++ b/packages/oxc/package.json @@ -55,14 +55,15 @@ "devDependencies": { "@humanwhocodes/momoa": "catalog:frontend", "@nuxt/kit": "catalog:build", - "@nuxt/ui": "catalog:frontend", "@types/picomatch": "catalog:types", + "@unocss/nuxt": "catalog:build", "@vitejs/devtools": "workspace:*", "@vitejs/devtools-kit": "workspace:*", "@vitejs/devtools-ui": "workspace:*", "@vueuse/core": "catalog:frontend", "@vueuse/nuxt": "catalog:build", "devframe": "catalog:deps", + "floating-vue": "catalog:frontend", "modern-monaco": "catalog:frontend", "nuxt": "catalog:build", "oxfmt": "catalog:devtools", @@ -70,10 +71,11 @@ "pathe": "catalog:deps", "picomatch": "catalog:frontend", "shiki": "catalog:frontend", - "tailwindcss": "catalog:build", + "theme-vitesse": "catalog:frontend", "tsdown": "catalog:build", "tsx": "catalog:build", "typescript": "catalog:devtools", + "unocss": "catalog:build", "vite": "catalog:build", "vue": "catalog:deps", "vue-router": "catalog:frontend" diff --git a/packages/oxc/src/app/app.config.ts b/packages/oxc/src/app/app.config.ts deleted file mode 100644 index 86415e2ae..000000000 --- a/packages/oxc/src/app/app.config.ts +++ /dev/null @@ -1,16 +0,0 @@ -export default defineAppConfig({ - ui: { - card: { - slots: { - root: 'rounded-lg', - header: 'py-2 px-4 sm:px-4', - body: 'p-0 sm:p-0', - footer: 'p-4 sm:px-6', - }, - }, - colors: { - primary: 'cyan', - neutral: 'zinc', - }, - }, -}) diff --git a/packages/oxc/src/app/app.vue b/packages/oxc/src/app/app.vue index bccb00461..7a793338a 100644 --- a/packages/oxc/src/app/app.vue +++ b/packages/oxc/src/app/app.vue @@ -1,17 +1,18 @@ diff --git a/packages/oxc/src/app/assets/css/main.css b/packages/oxc/src/app/assets/css/main.css index 2a7f40c48..f90aaf31a 100644 --- a/packages/oxc/src/app/assets/css/main.css +++ b/packages/oxc/src/app/assets/css/main.css @@ -1,51 +1,67 @@ -@import 'tailwindcss'; -@import '@nuxt/ui'; -@custom-variant dark (&:where(.dark, .dark *)); +@import '@vitejs/devtools-ui/styles/global.css'; -body { - background-color: unset; - @apply text-neutral-800 dark:text-neutral-300; +/* Floating Vue tooltips / dropdowns — align to the shared semantic tokens. */ +.v-popper--theme-dropdown .v-popper__inner, +.v-popper--theme-tooltip .v-popper__inner { + --uno: bg-tooltip color-base font-sans rounded border border-base shadow dark: shadow-2xl; + box-shadow: 0 6px 30px #0000001a; } -.bg-dots { - background-image: url('/dot-grid-light.png'); - background-size: 50px; - background-repeat: repeat; +.v-popper--theme-dropdown .v-popper__inner { + max-width: 50vw; + max-height: 50vh; + overflow: auto; } -.dark .bg-dots, -.bg-dots.dark { - color-scheme: dark; - background-color: black; - background-image: url('/dot-grid-dark.png'); +.v-popper--theme-tooltip .v-popper__arrow-inner, +.v-popper--theme-dropdown .v-popper__arrow-inner { + visibility: visible; + --uno: border-solid border-white dark: border-#111; } -.shiki, -.shiki span { - color: var(--shiki-dark) !important; - background-color: var(--ui-bg) !important; +.v-popper--theme-tooltip .v-popper__arrow-outer, +.v-popper--theme-dropdown .v-popper__arrow-outer { + --uno: border-solid border-base; } -.summary-card { - @apply border gap-1 border-neutral-200 dark:border-neutral-700 rounded-sm px-2 py-1 flex items-center; +/* Shiki code blocks: drop Shiki's baked-in theme background (an inline style, + so `!important` is required) and let the host surface show through. Light + mode keeps Shiki's inline light colors; dark mode swaps to the dual-theme + `--shiki-dark` values, again overriding the inline color. */ +.shiki, +.shiki span { + background-color: transparent !important; } -.color-scale-neutral { - @apply text-gray-700/75 dark:text-gray-300/75; +.dark .shiki, +.dark .shiki span { + color: var(--shiki-dark) !important; } -.color-scale-low { - @apply text-lime-700/75 dark:text-lime-300/75 dark:saturate-50; +/* Monaco */ +.monaco-editor, +.monaco-editor .margin, +.monaco-editor .view-lines, +.monaco-editor .view-line, +.monaco-editor .line-numbers { + font-family: 'Input Mono', 'FiraCode', monospace !important; + font-size: 13px !important; } -.color-scale-medium { - @apply text-amber-700/85 dark:text-amber-300/85 dark:saturate-80; +.monaco-editor, +.monaco-editor .monaco-editor-background, +.monaco-editor .overflow-guard, +.monaco-editor .margin { + background-color: transparent !important; } -.color-scale-high { - @apply text-orange-700/95 dark:text-orange-300/95; +.monaco-scrollable-element > .scrollbar > .slider { + background-color: var(--app-scrollbar-thumb) !important; + border-radius: var(--app-scrollbar-radius) !important; + transition: background 0.2s ease; } -.color-scale-critical { - @apply text-red-700/95 dark:text-red-300/95; +.monaco-scrollable-element > .scrollbar > .slider.active, +.monaco-scrollable-element > .scrollbar > .slider:hover { + background-color: var(--app-scrollbar-thumb-hover) !important; } diff --git a/packages/oxc/src/app/components/Back.vue b/packages/oxc/src/app/components/Back.vue index ecf2f34e0..b42246176 100644 --- a/packages/oxc/src/app/components/Back.vue +++ b/packages/oxc/src/app/components/Back.vue @@ -14,13 +14,8 @@ function goBack() { diff --git a/packages/oxc/src/app/components/ColorModeButton.vue b/packages/oxc/src/app/components/ColorModeButton.vue deleted file mode 100644 index af106d99d..000000000 --- a/packages/oxc/src/app/components/ColorModeButton.vue +++ /dev/null @@ -1,27 +0,0 @@ - - - diff --git a/packages/oxc/src/app/components/CongratState.vue b/packages/oxc/src/app/components/CongratState.vue deleted file mode 100644 index 154d65e55..000000000 --- a/packages/oxc/src/app/components/CongratState.vue +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/packages/oxc/src/app/components/EmptyState.vue b/packages/oxc/src/app/components/EmptyState.vue deleted file mode 100644 index e69de29bb..000000000 diff --git a/packages/oxc/src/app/components/ErrorTooltip.vue b/packages/oxc/src/app/components/ErrorTooltip.vue index bdbbe3cf3..9909e4515 100644 --- a/packages/oxc/src/app/components/ErrorTooltip.vue +++ b/packages/oxc/src/app/components/ErrorTooltip.vue @@ -11,14 +11,12 @@ interface Props { const props = defineProps() -const severityClasses = computed(() => { - return props.message.severity === 'error' - ? 'bg-red-50 text-red-700 dark:bg-red-900/50 dark:text-red-300' - : 'bg-yellow-50 text-yellow-700 dark:bg-yellow-900/50 dark:text-yellow-300' +const severityBadge = computed(() => { + return props.message.severity === 'error' ? 'badge-color-red' : 'badge-color-amber' }) const severityIcon = computed(() => { - return props.message.severity === 'error' ? 'ph:x-circle' : 'ph:warning-circle' + return props.message.severity === 'error' ? 'i-ph-x-circle' : 'i-ph-warning-circle' }) const rpc = useRpc() @@ -29,58 +27,68 @@ function handleOpenInEditor() {