-
-
- Reports
-
+ return [
+ {
+ id: 'oxlint',
+ name: 'Oxlint',
+ info: oxlint,
+ configs: configFiles.value.filter(file => file.tool === 'oxlint'),
+ views: oxlintViews,
+ },
+ {
+ id: 'oxfmt',
+ name: 'Oxfmt',
+ info: overview.value.oxfmt,
+ configs: configFiles.value.filter(file => file.tool === 'oxfmt'),
+ views: oxfmtViews,
+ },
+ ]
+})
+
-
-
- Config
-
+
+
+
-
+
+
+
+
+ {{ tool.name }}
+
-
-
- oxfmt
+
-
-
-
-
diff --git a/packages/oxc/src/app/pages/lint/report/[id].vue b/packages/oxc/src/app/pages/lint/report/[id].vue
deleted file mode 100644
index d962eb8b..00000000
--- a/packages/oxc/src/app/pages/lint/report/[id].vue
+++ /dev/null
@@ -1,109 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/packages/oxc/src/app/pages/lint/report/index.vue b/packages/oxc/src/app/pages/lint/report/index.vue
deleted file mode 100644
index c09593bf..00000000
--- a/packages/oxc/src/app/pages/lint/report/index.vue
+++ /dev/null
@@ -1,71 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
Select a lint session to get started:
-
-
-
-
-
-
-
-
-
-
-
-
- Oxc Inspector logs directory .devtools-oxc not found.
-
- Run npx @vitejs/devtools-oxc lint to generate it first.
-
- Read more:
-
- https://github.com/yuyinws/oxc-inspector
-
-
-
-
-
-
-
-
diff --git a/packages/oxc/src/app/pages/oxfmt.vue b/packages/oxc/src/app/pages/oxfmt.vue
new file mode 100644
index 00000000..ce0a60a1
--- /dev/null
+++ b/packages/oxc/src/app/pages/oxfmt.vue
@@ -0,0 +1,31 @@
+
+
+
+
+
diff --git a/packages/oxc/src/app/pages/fmt/config.vue b/packages/oxc/src/app/pages/oxfmt/config.vue
similarity index 100%
rename from packages/oxc/src/app/pages/fmt/config.vue
rename to packages/oxc/src/app/pages/oxfmt/config.vue
diff --git a/packages/oxc/src/app/pages/oxfmt/documents.vue b/packages/oxc/src/app/pages/oxfmt/documents.vue
new file mode 100644
index 00000000..8ef80656
--- /dev/null
+++ b/packages/oxc/src/app/pages/oxfmt/documents.vue
@@ -0,0 +1,10 @@
+
+
+
diff --git a/packages/oxc/src/app/pages/oxlint.vue b/packages/oxc/src/app/pages/oxlint.vue
new file mode 100644
index 00000000..a79f4b1e
--- /dev/null
+++ b/packages/oxc/src/app/pages/oxlint.vue
@@ -0,0 +1,36 @@
+
+
+
+
+
diff --git a/packages/oxc/src/app/pages/lint/config.vue b/packages/oxc/src/app/pages/oxlint/config.vue
similarity index 100%
rename from packages/oxc/src/app/pages/lint/config.vue
rename to packages/oxc/src/app/pages/oxlint/config.vue
diff --git a/packages/oxc/src/app/pages/oxlint/documents.vue b/packages/oxc/src/app/pages/oxlint/documents.vue
new file mode 100644
index 00000000..8eeeb0e5
--- /dev/null
+++ b/packages/oxc/src/app/pages/oxlint/documents.vue
@@ -0,0 +1,10 @@
+
+
+
diff --git a/packages/oxc/src/app/pages/oxlint/lint.vue b/packages/oxc/src/app/pages/oxlint/lint.vue
new file mode 100644
index 00000000..15a92faa
--- /dev/null
+++ b/packages/oxc/src/app/pages/oxlint/lint.vue
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
diff --git a/packages/oxc/src/app/pages/oxlint/lint/index.vue b/packages/oxc/src/app/pages/oxlint/lint/index.vue
new file mode 100644
index 00000000..023cf937
--- /dev/null
+++ b/packages/oxc/src/app/pages/oxlint/lint/index.vue
@@ -0,0 +1,130 @@
+
+
+
+
+
+
+
+
+
+
+
+
Select a lint result to inspect:
+
+
+
+
+
+
+ {{ isRunning ? 'Running…' : 'Run Lint' }}
+
+
+
+
+
+
+
+
+
+
+ Lint results will appear here after lint runs.
+
+
+
+ {{ isRunning ? 'Running…' : 'Run Lint' }}
+
+
+
+
+ Delete lint result
+
+
Delete lint result {{ selectedResultId }}?
+
+ Cancel
+
+ {{ isDeleting ? 'Deleting…' : 'Delete' }}
+
+
+
+
+
+
diff --git a/packages/oxc/src/commands/fmt.ts b/packages/oxc/src/commands/fmt.ts
deleted file mode 100644
index acb6ccd8..00000000
--- a/packages/oxc/src/commands/fmt.ts
+++ /dev/null
@@ -1 +0,0 @@
-export const fmt = ''
diff --git a/packages/oxc/src/commands/lint.ts b/packages/oxc/src/commands/lint.ts
deleted file mode 100644
index 15746810..00000000
--- a/packages/oxc/src/commands/lint.ts
+++ /dev/null
@@ -1,90 +0,0 @@
-import { intro, outro, spinner, log } from '@clack/prompts'
-import { define } from 'gunshi'
-import {
- execOxlintCommand,
- getOxlintConfig,
- getOxlintVersion,
- groupByFilename,
-} from '../node/utils/oxlint'
-import { mkdir, readFile, writeFile } from 'node:fs/promises'
-import { cwd } from 'node:process'
-import c from 'ansis'
-import { relative, resolve } from 'pathe'
-import { version } from '../../package.json'
-
-export const lint = define({
- name: 'lint',
- description: 'Generate oxlint logs',
- run: async ({ _ }) => {
- const spin = spinner()
-
- intro(`Oxc Inspector ${c.cyan(`v${version}`)}`)
-
- const gitignorePath = resolve(cwd(), '.gitignore')
- let appended = false
- try {
- const content = await readFile(gitignorePath, 'utf-8')
- const hasEntry = content.split('\n').some(line => {
- const trimmed = line.trim()
- return trimmed !== '' && !trimmed.startsWith('#') && /\.devtools-oxc/.test(trimmed)
- })
- if (!hasEntry) {
- const append = content.endsWith('\n') ? '.devtools-oxc\n' : '\n.devtools-oxc\n'
- await writeFile(gitignorePath, content + append, 'utf-8')
- appended = true
- }
- } catch (err) {
- if ((err as NodeJS.ErrnoException).code === 'ENOENT') {
- await writeFile(gitignorePath, '.devtools-oxc\n', 'utf-8')
- appended = true
- } else {
- throw err
- }
- }
- if (appended) {
- log.info('Appended .devtools-oxc to .gitignore')
- }
-
- spin.start('Running Oxlint...')
-
- const oxLintVersion = await getOxlintVersion()
- const config = await getOxlintConfig()
- const rawOutput = execOxlintCommand(_)
- const groupedOutput = await groupByFilename(rawOutput)
-
- const logsRootDir = resolve(cwd(), '.devtools-oxc', 'lint')
- await mkdir(logsRootDir, { recursive: true })
- const sessionId = Date.now()
- const sessionDir = resolve(logsRootDir, String(sessionId))
- await mkdir(sessionDir, { recursive: true })
- await writeFile(
- resolve(sessionDir, 'meta.json'),
- JSON.stringify(
- {
- version: oxLintVersion,
- timestamp: sessionId,
- summary: groupedOutput.summary,
- },
- null,
- 2,
- ),
- 'utf-8',
- )
- await writeFile(
- resolve(sessionDir, 'logs.json'),
- JSON.stringify(
- {
- files: groupedOutput.files,
- config: config ? JSON.parse(config) : null,
- },
- null,
- 2,
- ),
- 'utf-8',
- )
- spin.stop()
-
- outro(`Oxlint logs generated in ${c.cyan(relative(cwd(), sessionDir))}`)
- process.exit(0)
- },
-})
diff --git a/packages/oxc/src/commands/main.ts b/packages/oxc/src/commands/main.ts
deleted file mode 100644
index f112fab0..00000000
--- a/packages/oxc/src/commands/main.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { define } from 'gunshi'
-import { createDevServer } from 'devframe/adapters/dev'
-import c from 'ansis'
-import { log } from '@clack/prompts'
-import { oxcDevframe, OXC_DEVTOOLS_BASE } from '../node/devframe'
-
-export const mainCommand = define({
- name: 'main',
- description: 'Start oxc-devtools ui',
- run: async () => {
- // Spin up the devframe-powered dev server (h3 + WebSocket RPC + the SPA).
- // We drive it directly from gunshi rather than devframe's `createCli` so the
- // CLI shell stays framework-agnostic.
- await createDevServer(oxcDevframe, {
- onReady: ({ origin }) => {
- log.info(`Oxc Inspector UI is running on ${c.cyan(`${origin}${OXC_DEVTOOLS_BASE}`)}`)
- },
- })
- },
-})
diff --git a/packages/oxc/src/index.ts b/packages/oxc/src/index.ts
index e4cbbbd4..0277ad57 100644
--- a/packages/oxc/src/index.ts
+++ b/packages/oxc/src/index.ts
@@ -1,14 +1,19 @@
import { argv } from 'node:process'
-import { cli } from 'gunshi'
-import { mainCommand } from './commands/main'
-import { lint } from './commands/lint'
+import cac from 'cac'
+import { createDevServer } from 'devframe/adapters/dev'
import { version } from '../package.json'
+import { oxcDevframe, OXC_DEVTOOLS_BASE } from './node/devframe'
-cli(argv.slice(2), mainCommand, {
- name: 'oxc-devtools',
- version,
- renderHeader: () => Promise.resolve(''),
- subCommands: {
- lint,
- },
+const cli = cac('oxc-devtools')
+
+cli.command('', 'Start Oxc DevTools').action(async () => {
+ await createDevServer(oxcDevframe, {
+ onReady: ({ origin }) => {
+ console.log(`Oxc Inspector UI is running on ${origin}${OXC_DEVTOOLS_BASE}`)
+ },
+ })
})
+
+cli.version(version)
+cli.help()
+cli.parse(argv)
diff --git a/packages/oxc/src/modules/rpc.js b/packages/oxc/src/modules/rpc.ts
similarity index 74%
rename from packages/oxc/src/modules/rpc.js
rename to packages/oxc/src/modules/rpc.ts
index 4b83a577..ba2813e0 100644
--- a/packages/oxc/src/modules/rpc.js
+++ b/packages/oxc/src/modules/rpc.ts
@@ -1,6 +1,6 @@
import { addVitePlugin, defineNuxtModule } from '@nuxt/kit'
import { DevTools } from '@vitejs/devtools'
-import { DevToolsOxc } from '../../src/vite'
+import { DevToolsOxc } from '../vite'
export default defineNuxtModule({
meta: {
@@ -10,7 +10,7 @@ export default defineNuxtModule({
async setup() {
addVitePlugin(DevToolsOxc())
- const devtools = await DevTools()
+ const devtools = await DevTools({ builtinDevTools: false })
addVitePlugin(devtools)
},
})
diff --git a/packages/oxc/src/node/__tests__/config-files.test.ts b/packages/oxc/src/node/__tests__/config-files.test.ts
new file mode 100644
index 00000000..93fb59ea
--- /dev/null
+++ b/packages/oxc/src/node/__tests__/config-files.test.ts
@@ -0,0 +1,74 @@
+import { execFile as execFileCallback } from 'node:child_process'
+import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises'
+import { tmpdir } from 'node:os'
+import { join } from 'node:path'
+import { promisify } from 'node:util'
+import { afterEach, describe, expect, it } from 'vitest'
+import { getOxcConfigFiles } from '../utils/config-files'
+
+const execFile = promisify(execFileCallback)
+const fixtures: string[] = []
+
+async function createFixture() {
+ const cwd = await mkdtemp(join(tmpdir(), 'oxc-config-files-'))
+ fixtures.push(cwd)
+ await execFile('git', ['init', '--quiet', cwd])
+ return cwd
+}
+
+afterEach(async () => {
+ await Promise.all(fixtures.splice(0).map(dir => rm(dir, { recursive: true, force: true })))
+})
+
+describe('getOxcConfigFiles', () => {
+ it('finds nested Oxlint and Oxfmt config files', async () => {
+ const cwd = await createFixture()
+ await mkdir(join(cwd, 'packages', 'app'), { recursive: true })
+ await Promise.all([
+ writeFile(join(cwd, '.oxlintrc.json'), '{}'),
+ writeFile(join(cwd, 'packages', 'app', 'oxlint.config.mts'), 'export default {}'),
+ writeFile(join(cwd, 'packages', 'app', '.oxfmtrc.jsonc'), '{}'),
+ ])
+
+ await expect(getOxcConfigFiles(cwd)).resolves.toEqual([
+ expect.objectContaining({ path: '.oxlintrc.json', tool: 'oxlint', source: 'oxc' }),
+ expect.objectContaining({
+ path: 'packages/app/.oxfmtrc.jsonc',
+ tool: 'oxfmt',
+ source: 'oxc',
+ }),
+ expect.objectContaining({
+ path: 'packages/app/oxlint.config.mts',
+ tool: 'oxlint',
+ source: 'oxc',
+ }),
+ ])
+ })
+
+ it('skips directories ignored by .gitignore', async () => {
+ const cwd = await createFixture()
+ await mkdir(join(cwd, 'ignored'), { recursive: true })
+ await Promise.all([
+ writeFile(join(cwd, '.gitignore'), 'ignored/\n'),
+ writeFile(join(cwd, 'ignored', '.oxlintrc.json'), '{}'),
+ ])
+
+ await expect(getOxcConfigFiles(cwd)).resolves.toEqual([])
+ })
+
+ it('recognizes lint and fmt fields in a Vite Plus config without loading it', async () => {
+ const cwd = await createFixture()
+ await writeFile(
+ join(cwd, 'vite.config.ts'),
+ `
+ import { defineConfig } from 'vite-plus'
+ export default defineConfig({ lint: {}, fmt: {} })
+ `,
+ )
+
+ await expect(getOxcConfigFiles(cwd)).resolves.toEqual([
+ expect.objectContaining({ path: 'vite.config.ts', tool: 'oxlint', source: 'vite-plus' }),
+ expect.objectContaining({ path: 'vite.config.ts', tool: 'oxfmt', source: 'vite-plus' }),
+ ])
+ })
+})
diff --git a/packages/oxc/src/node/__tests__/lint-results.test.ts b/packages/oxc/src/node/__tests__/lint-results.test.ts
new file mode 100644
index 00000000..b225cd00
--- /dev/null
+++ b/packages/oxc/src/node/__tests__/lint-results.test.ts
@@ -0,0 +1,73 @@
+import { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises'
+import { tmpdir } from 'node:os'
+import { join } from 'node:path'
+import { afterEach, expect, it } from 'vitest'
+import { LintResultsManager } from '../utils/lint-results-manager'
+import { ensureOxcGitignored, parseOxlintOutput } from '../utils/oxlint'
+
+const fixtures: string[] = []
+
+async function createFixture() {
+ const root = await mkdtemp(join(tmpdir(), 'oxc-lint-results-'))
+ fixtures.push(root)
+ return root
+}
+
+afterEach(async () => {
+ await Promise.all(fixtures.splice(0).map(dir => rm(dir, { recursive: true, force: true })))
+})
+
+it('parses and persists lint results', async () => {
+ const root = await createFixture()
+ await writeFile(join(root, 'input.ts'), 'const answer = 42\n')
+ const output = await parseOxlintOutput(
+ JSON.stringify({
+ diagnostics: [
+ {
+ filename: 'input.ts',
+ severity: 'warning',
+ labels: [{ span: { line: 1 } }],
+ },
+ ],
+ number_of_files: 1,
+ number_of_rules: 100,
+ threads_count: 1,
+ start_time: 0.01,
+ }),
+ root,
+ )
+ const manager = new LintResultsManager(join(root, '.devtools-oxc', 'lint'))
+ const meta = { version: '1.0.0', timestamp: 123, summary: output.summary }
+ const logs = { files: output.files, config: null }
+
+ await manager.create(meta, logs)
+
+ await expect(manager.list()).resolves.toEqual([meta])
+ await expect(manager.load('123')).resolves.toEqual({ meta, logs })
+ await manager.delete('123')
+ await expect(manager.list()).resolves.toEqual([])
+})
+
+it('keeps an existing .devtools-oxc gitignore rule', async () => {
+ const root = await createFixture()
+ const gitignore = join(root, '.gitignore')
+ await writeFile(gitignore, '**/.devtools-oxc/**\n')
+
+ await ensureOxcGitignored(root)
+
+ await expect(readFile(gitignore, 'utf-8')).resolves.toBe('**/.devtools-oxc/**\n')
+})
+
+it('does not create a missing .gitignore', async () => {
+ const root = await createFixture()
+ const gitignore = join(root, '.gitignore')
+
+ await ensureOxcGitignored(root)
+
+ await expect(readFile(gitignore, 'utf-8')).rejects.toMatchObject({ code: 'ENOENT' })
+})
+
+it('rejects JSON that is not an oxlint result', async () => {
+ const root = await createFixture()
+ await expect(parseOxlintOutput('{}', root)).resolves.toBeNull()
+})
diff --git a/packages/oxc/src/node/devframe.ts b/packages/oxc/src/node/devframe.ts
index f226986f..5b6f2eab 100644
--- a/packages/oxc/src/node/devframe.ts
+++ b/packages/oxc/src/node/devframe.ts
@@ -13,7 +13,7 @@ export const OXC_DEVTOOLS_BASE = '/__devtools-oxc/'
*
* - **embedded** in Vite DevTools via kit's `createPluginFromDevframe`
* (see `../vite.ts`), and
- * - **standalone** via devframe's `createDevServer` (see `../commands/main.ts`).
+ * - **standalone** via devframe's `createDevServer` (see `../../index.ts`).
*
* `setup(ctx)` only registers RPC functions — the SPA hosting and dock entry
* are derived from this metadata by the respective adapter.
diff --git a/packages/oxc/src/node/diagnostics.ts b/packages/oxc/src/node/diagnostics.ts
index bb53e78e..e64297aa 100644
--- a/packages/oxc/src/node/diagnostics.ts
+++ b/packages/oxc/src/node/diagnostics.ts
@@ -1,18 +1,22 @@
import { createConsoleReporter, defineDiagnostics } from 'nostics'
// OXDT — structured diagnostics for `@vitejs/devtools-oxc`.
-//
-// This is the reserved prefix scaffold. The node-side code imported from
-// `oxc-inspector` still emits ad-hoc `console.warn` / `throw`; migrating those
-// call sites onto these coded diagnostics is a tracked follow-up (see the oxc
-// import PR). Add new codes sequentially (OXDT0001, OXDT0002, …).
export const diagnostics = /* #__PURE__ */ defineDiagnostics({
docsBase: 'https://devtools.vite.dev/errors',
- reporters: [createConsoleReporter()],
+ reporters: [/* #__PURE__ */ createConsoleReporter()],
codes: {
OXDT0001: {
- why: 'Oxc logs directory `.devtools-oxc` not found, you might want to run build with `npx @vitejs/devtools-oxc` to generate it first.',
- fix: 'Run `npx @vitejs/devtools-oxc lint` to generate lint logs before launching the UI.',
+ why: (p: { reason: string }) => `Failed to create a lint result: ${p.reason}`,
+ fix: 'Check that oxlint is installed, its configuration is valid, and the project directory is writable.',
+ },
+ OXDT0002: {
+ why: (p: { resultId: string }) => `Invalid lint result ID "${p.resultId}".`,
+ fix: 'Use the numeric ID shown in the lint result list.',
+ },
+ OXDT0003: {
+ why: (p: { resultId: string; reason: string }) =>
+ `Failed to delete lint result "${p.resultId}": ${p.reason}`,
+ fix: 'Check that the lint result exists and the project directory is writable.',
},
},
})
diff --git a/packages/oxc/src/node/rpc/functions/get-config-files.ts b/packages/oxc/src/node/rpc/functions/get-config-files.ts
new file mode 100644
index 00000000..8ea5daae
--- /dev/null
+++ b/packages/oxc/src/node/rpc/functions/get-config-files.ts
@@ -0,0 +1,12 @@
+import { getOxcConfigFiles } from '../../utils/config-files'
+import { defineOxcRpc } from '../_define'
+
+export const getConfigFiles = defineOxcRpc({
+ name: 'devtools-oxc:get-config-files',
+ type: 'query',
+ jsonSerializable: true,
+ cacheable: true,
+ setup: ctx => ({
+ handler: () => getOxcConfigFiles(ctx.workspaceRoot),
+ }),
+})
diff --git a/packages/oxc/src/node/rpc/functions/oxlint-capabilities.ts b/packages/oxc/src/node/rpc/functions/oxlint-capabilities.ts
new file mode 100644
index 00000000..f4ab4b1f
--- /dev/null
+++ b/packages/oxc/src/node/rpc/functions/oxlint-capabilities.ts
@@ -0,0 +1,17 @@
+import type { DevframeNodeContext } from 'devframe/types'
+import { defineOxcRpc } from '../_define'
+
+const enabledContexts = new WeakSet
()
+
+export function enableOxlintRun(context: DevframeNodeContext) {
+ enabledContexts.add(context)
+}
+
+export const oxlintCapabilities = defineOxcRpc({
+ name: 'devtools-oxc:lint-capabilities',
+ type: 'query',
+ jsonSerializable: true,
+ setup: context => ({
+ handler: () => ({ canRun: enabledContexts.has(context) }),
+ }),
+})
diff --git a/packages/oxc/src/node/rpc/functions/oxlint-delete-result.ts b/packages/oxc/src/node/rpc/functions/oxlint-delete-result.ts
new file mode 100644
index 00000000..8102545c
--- /dev/null
+++ b/packages/oxc/src/node/rpc/functions/oxlint-delete-result.ts
@@ -0,0 +1,23 @@
+import { Diagnostic } from 'nostics'
+import { diagnostics } from '../../diagnostics'
+import { defineOxcRpc } from '../_define'
+import { getLintResultsManager } from '../utils'
+
+export const oxlintDeleteResult = defineOxcRpc({
+ name: 'devtools-oxc:delete-lint-result',
+ type: 'action',
+ setup: context => ({
+ handler: async ({ resultId }: { resultId: string }) => {
+ try {
+ await getLintResultsManager(context).delete(resultId)
+ } catch (error) {
+ if (error instanceof Diagnostic) throw error
+ throw diagnostics.OXDT0003({
+ resultId,
+ reason: error instanceof Error ? error.message : String(error),
+ cause: error,
+ })
+ }
+ },
+ }),
+})
diff --git a/packages/oxc/src/node/rpc/functions/oxlint-get-result.ts b/packages/oxc/src/node/rpc/functions/oxlint-get-result.ts
new file mode 100644
index 00000000..c6c3f0c4
--- /dev/null
+++ b/packages/oxc/src/node/rpc/functions/oxlint-get-result.ts
@@ -0,0 +1,12 @@
+import { defineOxcRpc } from '../_define'
+import { getLintResultsManager } from '../utils'
+
+export const oxlintGetResult = defineOxcRpc({
+ name: 'devtools-oxc:get-lint-result',
+ type: 'query',
+ jsonSerializable: true,
+ cacheable: true,
+ setup: context => ({
+ handler: ({ resultId }: { resultId: string }) => getLintResultsManager(context).load(resultId),
+ }),
+})
diff --git a/packages/oxc/src/node/rpc/functions/oxlint-get-session.ts b/packages/oxc/src/node/rpc/functions/oxlint-get-session.ts
deleted file mode 100644
index 8e50a543..00000000
--- a/packages/oxc/src/node/rpc/functions/oxlint-get-session.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { defineOxcRpc } from '../_define'
-import { getLogsManager } from '../utils'
-
-export const oxlintGetSession = defineOxcRpc({
- name: 'devtools-oxc:get-lint-session',
- type: 'query',
- jsonSerializable: true,
- cacheable: true,
- setup: context => {
- return {
- handler: async ({ sessionId }: { sessionId: string }) => {
- const logsManager = getLogsManager(context)
- const session = await logsManager.loadSession(sessionId)
- return session
- },
- }
- },
-})
diff --git a/packages/oxc/src/node/rpc/functions/oxlint-list-results.ts b/packages/oxc/src/node/rpc/functions/oxlint-list-results.ts
new file mode 100644
index 00000000..c719082b
--- /dev/null
+++ b/packages/oxc/src/node/rpc/functions/oxlint-list-results.ts
@@ -0,0 +1,11 @@
+import { defineOxcRpc } from '../_define'
+import { getLintResultsManager } from '../utils'
+
+export const oxlintListResults = defineOxcRpc({
+ name: 'devtools-oxc:list-lint-results',
+ type: 'query',
+ jsonSerializable: true,
+ setup: context => ({
+ handler: () => getLintResultsManager(context).list(),
+ }),
+})
diff --git a/packages/oxc/src/node/rpc/functions/oxlint-list-sessions.ts b/packages/oxc/src/node/rpc/functions/oxlint-list-sessions.ts
deleted file mode 100644
index fe644bf7..00000000
--- a/packages/oxc/src/node/rpc/functions/oxlint-list-sessions.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { defineOxcRpc } from '../_define'
-import { getLogsManager } from '../utils'
-
-export const oxlintListSessions = defineOxcRpc({
- name: 'devtools-oxc:list-lint-session',
- type: 'query',
- jsonSerializable: true,
- setup: context => {
- return {
- handler: async () => {
- const logsManager = getLogsManager(context)
- const sessions = await logsManager.list()
- return sessions
- },
- }
- },
-})
diff --git a/packages/oxc/src/node/rpc/functions/oxlint-run.ts b/packages/oxc/src/node/rpc/functions/oxlint-run.ts
new file mode 100644
index 00000000..76b8fd3e
--- /dev/null
+++ b/packages/oxc/src/node/rpc/functions/oxlint-run.ts
@@ -0,0 +1,82 @@
+import { defineRpcFunction, type KitNodeContext } from '@vitejs/devtools-kit'
+import { Diagnostic } from 'nostics'
+import { x } from 'tinyexec'
+import { diagnostics } from '../../diagnostics'
+import { ensureOxcGitignored, getOxlintConfig, parseOxlintOutput } from '../../utils/oxlint'
+import { getLintResultsManager } from '../utils'
+
+export const oxlintRun = defineRpcFunction({
+ name: 'devtools-oxc:run-lint',
+ type: 'action',
+ setup: context => {
+ let running: Promise | undefined
+ return {
+ handler: () => {
+ running ??= runLint(context).finally(() => {
+ running = undefined
+ })
+ return running
+ },
+ }
+ },
+})
+
+async function runLint(context: KitNodeContext) {
+ const { terminals } = context
+ const root = context.cwd
+ const timestamp = Date.now()
+ let terminal: Awaited> | undefined
+
+ try {
+ await ensureOxcGitignored(root)
+ const versionResult = await x('oxlint', ['--version'], { nodeOptions: { cwd: root } })
+ const version = versionResult.stdout.trim().split(/\s+/).at(-1)
+ if (versionResult.exitCode !== 0 || !version)
+ throw diagnostics.OXDT0001({
+ reason: versionResult.stderr.trim() || 'Unable to read the oxlint version',
+ })
+
+ terminal = await terminals.startChildProcess(
+ {
+ command: 'oxlint',
+ args: ['-f', 'json'],
+ cwd: root,
+ env: { FORCE_COLOR: '0', NO_COLOR: '1' },
+ },
+ {
+ id: `devtools-oxc:lint:${timestamp}`,
+ title: 'Oxlint',
+ icon: 'ph:terminal-window-duotone',
+ },
+ )
+ const { stdout, stderr, exitCode } = await terminal.getResult()
+ if (exitCode === undefined)
+ throw diagnostics.OXDT0001({ reason: 'Oxlint was terminated before it completed' })
+
+ let output
+ try {
+ output = await parseOxlintOutput(stdout, root)
+ } catch (error) {
+ throw diagnostics.OXDT0001({
+ reason: stderr.trim() || 'Oxlint returned invalid JSON',
+ cause: error,
+ })
+ }
+ if (!output) throw diagnostics.OXDT0001({ reason: 'Oxlint returned an invalid JSON result' })
+
+ const config = await getOxlintConfig(root)
+ await getLintResultsManager(context).create(
+ { version, timestamp, summary: output.summary },
+ { files: output.files, config: config ? JSON.parse(config) : null },
+ )
+ terminals.update({ ...terminal, status: 'stopped' })
+ return timestamp
+ } catch (error) {
+ if (terminal) terminals.update({ ...terminal, status: 'error' })
+ if (error instanceof Diagnostic) throw error
+ throw diagnostics.OXDT0001({
+ reason: error instanceof Error ? error.message : String(error),
+ cause: error,
+ })
+ }
+}
diff --git a/packages/oxc/src/node/rpc/index.ts b/packages/oxc/src/node/rpc/index.ts
index 42c38da2..cea46bc6 100644
--- a/packages/oxc/src/node/rpc/index.ts
+++ b/packages/oxc/src/node/rpc/index.ts
@@ -1,22 +1,33 @@
import type { RpcDefinitionsToFunctions } from '@vitejs/devtools-kit'
-import { oxlintGetSession } from './functions/oxlint-get-session'
-import { oxlintListSessions } from './functions/oxlint-list-sessions'
+import { oxlintCapabilities } from './functions/oxlint-capabilities'
+import { oxlintDeleteResult } from './functions/oxlint-delete-result'
+import { oxlintGetResult } from './functions/oxlint-get-result'
+import { oxlintListResults } from './functions/oxlint-list-results'
+import { oxlintRun } from './functions/oxlint-run'
import { overview } from './functions/overview'
import { oxlintGetConfigFile } from './functions/oxlint-get-config-file'
import { oxfmtGetConfigFile } from './functions/oxfmt-get-config-file'
import { openInEditor } from './functions/open-in-editor'
+import { getConfigFiles } from './functions/get-config-files'
import '@vitejs/devtools-kit'
export const rpcFunctions = [
- oxlintListSessions,
- oxlintGetSession,
+ oxlintCapabilities,
+ oxlintListResults,
+ oxlintGetResult,
+ oxlintDeleteResult,
overview,
oxlintGetConfigFile,
oxfmtGetConfigFile,
+ getConfigFiles,
openInEditor,
] as const
-export type ServerFunctions = RpcDefinitionsToFunctions
+export const viteRpcFunctions = [oxlintRun] as const
+
+export type ServerFunctions = RpcDefinitionsToFunctions<
+ readonly [...typeof rpcFunctions, ...typeof viteRpcFunctions]
+>
declare module '@vitejs/devtools-kit' {
export interface DevToolsRpcServerFunctions extends ServerFunctions {}
diff --git a/packages/oxc/src/node/rpc/utils.ts b/packages/oxc/src/node/rpc/utils.ts
index 01860133..9d779ffb 100644
--- a/packages/oxc/src/node/rpc/utils.ts
+++ b/packages/oxc/src/node/rpc/utils.ts
@@ -1,19 +1,19 @@
import type { DevframeNodeContext } from 'devframe/types'
import { join } from 'pathe'
-import { OxlintLogsManager } from '../utils/logs-manager'
+import { LintResultsManager } from '../utils/lint-results-manager'
-const weakMap = new WeakMap()
+const weakMap = new WeakMap()
-export function getLogsManager(context: DevframeNodeContext): OxlintLogsManager {
+export function getLintResultsManager(context: DevframeNodeContext): LintResultsManager {
let manager = weakMap.get(context)!
if (!manager) {
const dir = join(context.cwd ?? process.cwd(), '.devtools-oxc', 'lint')
- manager = new OxlintLogsManager(dir)
+ manager = new LintResultsManager(dir)
weakMap.set(context, manager)
}
return manager
}
-export function setLogsManager(context: DevframeNodeContext, manager: OxlintLogsManager) {
+export function setLintResultsManager(context: DevframeNodeContext, manager: LintResultsManager) {
weakMap.set(context, manager)
}
diff --git a/packages/oxc/src/node/utils/config-files.ts b/packages/oxc/src/node/utils/config-files.ts
new file mode 100644
index 00000000..a4c23a00
--- /dev/null
+++ b/packages/oxc/src/node/utils/config-files.ts
@@ -0,0 +1,99 @@
+import { execFile as execFileCallback } from 'node:child_process'
+import { readdir, readFile } from 'node:fs/promises'
+import { join, relative } from 'pathe'
+import { promisify } from 'node:util'
+
+const execFile = promisify(execFileCallback)
+
+const CONFIG_FILES = {
+ '.oxlintrc.json': { tool: 'oxlint', format: 'json' },
+ '.oxlintrc.jsonc': { tool: 'oxlint', format: 'jsonc' },
+ 'oxlint.config.ts': { tool: 'oxlint', format: 'ts' },
+ 'oxlint.config.mts': { tool: 'oxlint', format: 'mts' },
+ '.oxfmtrc.json': { tool: 'oxfmt', format: 'json' },
+ '.oxfmtrc.jsonc': { tool: 'oxfmt', format: 'jsonc' },
+ 'oxfmt.config.ts': { tool: 'oxfmt', format: 'ts' },
+ 'oxfmt.config.mts': { tool: 'oxfmt', format: 'mts' },
+} as const
+
+const VITE_PLUS_CONFIG_FIELDS = {
+ lint: 'oxlint',
+ fmt: 'oxfmt',
+} as const
+
+async function getIgnoredDirectories(cwd: string) {
+ try {
+ const { stdout } = await execFile('git', [
+ '-C',
+ cwd,
+ 'ls-files',
+ '--others',
+ '--ignored',
+ '--exclude-standard',
+ '--directory',
+ '-z',
+ ])
+ return new Set(stdout.split('\0').filter(path => path.endsWith('/')))
+ } catch {
+ return new Set()
+ }
+}
+
+export async function getOxcConfigFiles(cwd: string) {
+ const files: Array<{
+ tool: 'oxlint' | 'oxfmt'
+ format: 'json' | 'jsonc' | 'ts' | 'mts' | 'js'
+ path: string
+ content: string
+ source: 'oxc' | 'vite-plus'
+ }> = []
+ const ignoredDirectories = await getIgnoredDirectories(cwd)
+
+ async function visit(dir: string): Promise {
+ const entries = await readdir(dir, { withFileTypes: true })
+ await Promise.all(
+ entries.map(async entry => {
+ const path = join(dir, entry.name)
+ if (entry.isDirectory()) {
+ const relativePath = relative(cwd, path)
+ if (
+ entry.name !== '.git' &&
+ entry.name !== 'node_modules' &&
+ !ignoredDirectories.has(`${relativePath}/`)
+ ) {
+ await visit(path)
+ }
+ return
+ }
+
+ const config = CONFIG_FILES[entry.name as keyof typeof CONFIG_FILES]
+ if (entry.isFile() && config) {
+ files.push({
+ ...config,
+ path: relative(cwd, path),
+ content: await readFile(path, 'utf-8'),
+ source: 'oxc',
+ })
+ }
+ if (entry.isFile() && /^vite\.config\.(ts|js)$/.test(entry.name)) {
+ const content = await readFile(path, 'utf-8')
+ const format = entry.name.endsWith('.ts') ? 'ts' : 'js'
+ for (const [field, tool] of Object.entries(VITE_PLUS_CONFIG_FIELDS)) {
+ if (new RegExp(`(?:^|[,{])\\s*${field}\\s*:`, 'm').test(content)) {
+ files.push({
+ tool,
+ format,
+ path: relative(cwd, path),
+ content,
+ source: 'vite-plus',
+ })
+ }
+ }
+ }
+ }),
+ )
+ }
+
+ await visit(cwd)
+ return files.sort((a, b) => a.path.localeCompare(b.path))
+}
diff --git a/packages/oxc/src/node/utils/lint-results-manager.ts b/packages/oxc/src/node/utils/lint-results-manager.ts
new file mode 100644
index 00000000..08bc0f0b
--- /dev/null
+++ b/packages/oxc/src/node/utils/lint-results-manager.ts
@@ -0,0 +1,62 @@
+import type { LintResultLogs, LintResultMeta } from '../../types'
+import { existsSync } from 'node:fs'
+import { mkdir, readdir, readFile, rm, writeFile } from 'node:fs/promises'
+import { join } from 'pathe'
+import { diagnostics } from '../diagnostics'
+
+export class LintResultsManager {
+ constructor(readonly dir: string) {}
+
+ async list(): Promise {
+ if (!existsSync(this.dir)) return []
+
+ const entries = await readdir(this.dir, { withFileTypes: true })
+ const results = await Promise.all(
+ entries
+ .filter(entry => entry.isDirectory() && /^\d+$/.test(entry.name))
+ .sort((a, b) => Number(b.name) - Number(a.name))
+ .map(async entry => {
+ try {
+ return JSON.parse(
+ await readFile(join(this.dir, entry.name, 'meta.json'), 'utf-8'),
+ ) as LintResultMeta
+ } catch {
+ return null
+ }
+ }),
+ )
+ return results.filter(result => result !== null)
+ }
+
+ async load(resultId: string): Promise<{ meta: LintResultMeta; logs: LintResultLogs } | null> {
+ this.validateId(resultId)
+ try {
+ const [meta, logs] = await Promise.all([
+ readFile(join(this.dir, resultId, 'meta.json'), 'utf-8'),
+ readFile(join(this.dir, resultId, 'logs.json'), 'utf-8'),
+ ])
+ return { meta: JSON.parse(meta), logs: JSON.parse(logs) }
+ } catch {
+ return null
+ }
+ }
+
+ async create(meta: LintResultMeta, logs: LintResultLogs) {
+ const resultDir = join(this.dir, String(meta.timestamp))
+ await mkdir(resultDir, { recursive: true })
+ await Promise.all([
+ writeFile(join(resultDir, 'meta.json'), JSON.stringify(meta, null, 2), 'utf-8'),
+ writeFile(join(resultDir, 'logs.json'), JSON.stringify(logs, null, 2), 'utf-8'),
+ ])
+ return meta.timestamp
+ }
+
+ async delete(resultId: string) {
+ this.validateId(resultId)
+ await rm(join(this.dir, resultId), { recursive: true })
+ }
+
+ private validateId(resultId: string) {
+ if (!/^\d+$/.test(resultId)) throw diagnostics.OXDT0002({ resultId })
+ }
+}
diff --git a/packages/oxc/src/node/utils/logs-manager.ts b/packages/oxc/src/node/utils/logs-manager.ts
deleted file mode 100644
index 23881512..00000000
--- a/packages/oxc/src/node/utils/logs-manager.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import type { Logs, Meta } from '../../types'
-import { existsSync } from 'node:fs'
-import { readdir, readFile, writeFile } from 'node:fs/promises'
-import { join } from 'pathe'
-
-export class OxlintLogsManager {
- constructor(readonly dir: string) {}
-
- async list(): Promise {
- if (!existsSync(this.dir)) {
- return []
- }
- const sessions = await readdir(this.dir, {
- withFileTypes: true,
- })
- const metas = await Promise.all(
- sessions
- .filter(entry => entry.isDirectory())
- .filter(entry => existsSync(join(this.dir, entry.name, 'meta.json')))
- .sort((a, b) => {
- return Number(b.name) - Number(a.name)
- })
- .map(async (entry): Promise => {
- const metaPath = join(this.dir, entry.name, 'meta.json')
- const content = await readFile(metaPath, 'utf-8')
- try {
- return JSON.parse(content)
- } catch {
- return null
- }
- }),
- )
- return metas.filter(Boolean)
- }
-
- async loadSession(session: string): Promise<{ meta: Meta; logs: Logs } | null> {
- try {
- const metaPath = join(this.dir, session, 'meta.json')
- const logsPath = join(this.dir, session, 'logs.json')
- const meta = await readFile(metaPath, 'utf-8')
- const logs = await readFile(logsPath, 'utf-8')
- return {
- meta: JSON.parse(meta),
- logs: JSON.parse(logs),
- }
- } catch {
- return null
- }
- }
-
- async createSession(meta: string, logs: string) {
- const session = new Date().getTime()
- const metaPath = join(this.dir, String(session), 'meta.json')
- const logsPath = join(this.dir, String(session), 'logs.json')
- await writeFile(metaPath, meta)
- await writeFile(logsPath, logs)
- return session
- }
-}
diff --git a/packages/oxc/src/node/utils/oxlint.ts b/packages/oxc/src/node/utils/oxlint.ts
index 4a68ab5a..e9f96dee 100644
--- a/packages/oxc/src/node/utils/oxlint.ts
+++ b/packages/oxc/src/node/utils/oxlint.ts
@@ -1,23 +1,13 @@
-import { execSync } from 'node:child_process'
-import { readFile } from 'node:fs/promises'
+import type { FileData, Message, Summary } from '../../types'
+import { appendFile, readFile } from 'node:fs/promises'
import { dirname } from 'node:path'
-import { cwd, exit } from 'node:process'
+import { cwd } from 'node:process'
import { fileURLToPath } from 'node:url'
import { resolve } from 'pathe'
-export async function getOxlintVersion() {
- try {
- const version = execSync('npx oxlint --version', { encoding: 'utf-8' })
- return version.split(' ')[1]?.replaceAll('\n', '') ?? undefined
- } catch {
- console.error('Oxlint is not installed, please install it first')
- exit(1)
- }
-}
-
-export async function getOxlintConfig() {
+export async function getOxlintConfig(root = cwd()) {
// Read the .oxlintrc.json file in the current directory
- const configPath = resolve(cwd(), '.oxlintrc.json')
+ const configPath = resolve(root, '.oxlintrc.json')
try {
const config = await readFile(configPath, 'utf-8')
@@ -27,91 +17,81 @@ export async function getOxlintConfig() {
}
}
-function wrapOxlintCommand(rawArgs: string[]) {
- const args = rawArgs.slice(1)
- const commandArgs = ['npx', '--yes', 'oxlint', '-f', 'json', ...args]
- return commandArgs.join(' ')
-}
-
-export function execOxlintCommand(rawArgs: string[]) {
+export async function ensureOxcGitignored(root: string) {
+ const gitignorePath = resolve(root, '.gitignore')
+ let content = ''
try {
- const oxlintCommand = wrapOxlintCommand(rawArgs)
- const output = execSync(oxlintCommand, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] })
- return output
+ content = await readFile(gitignorePath, 'utf-8')
} catch (error) {
- if (error instanceof Error && 'stdout' in error) {
- return error.stdout as string
- }
+ if ((error as NodeJS.ErrnoException).code === 'ENOENT') return
throw error
}
-}
-export const clientDir = resolve(dirname(fileURLToPath(import.meta.url)), './client/public')
-
-// Group diagnostics by filename
-export async function groupByFilename(oxlintOutput: string) {
- try {
- const data = JSON.parse(oxlintOutput)
- const diagnostics = data.diagnostics || []
+ if (
+ content.split('\n').some(line => {
+ const entry = line.trim()
+ return entry && !entry.startsWith('#') && entry.includes('.devtools-oxc')
+ })
+ )
+ return
- // Group by filename
- const grouped = diagnostics.reduce((acc: Record, diagnostic: any) => {
- const filename = diagnostic.filename
- if (!acc[filename]) {
- acc[filename] = {
- filename,
- lines: {},
- }
- }
-
- // Group by line
- const line = diagnostic.labels?.[0]?.span?.line || 1
- if (!acc[filename].lines[line]) {
- acc[filename].lines[line] = []
- }
- acc[filename].lines[line].push(diagnostic)
+ await appendFile(
+ gitignorePath,
+ `${content && !content.endsWith('\n') ? '\n' : ''}.devtools-oxc\n`,
+ )
+}
- return acc
- }, {})
+export async function parseOxlintOutput(rawOutput: string, root: string) {
+ const data = JSON.parse(rawOutput) as Record
+ const summaryFields = [
+ 'number_of_files',
+ 'number_of_rules',
+ 'threads_count',
+ 'start_time',
+ ] as const
+ if (
+ !data ||
+ !Array.isArray(data.diagnostics) ||
+ summaryFields.some(field => typeof data[field] !== 'number') ||
+ data.diagnostics.some(
+ diagnostic =>
+ !diagnostic ||
+ typeof diagnostic !== 'object' ||
+ typeof diagnostic.filename !== 'string' ||
+ typeof diagnostic.severity !== 'string' ||
+ !Array.isArray(diagnostic.labels),
+ )
+ )
+ return null
- // Convert to array format, turn the lines object into an array, and read each file's contents
- const result = await Promise.all(
- Object.values(grouped).map(async (file: any) => {
- let source = ''
- try {
- source = await readFile(file.filename, 'utf-8')
- } catch (error) {
- console.warn(`Can not read file ${file.filename}:`, error)
- source = ''
- }
+ const diagnostics = data.diagnostics as Message[]
+ const grouped = new Map>()
- return {
- filename: file.filename,
- source,
- lines: Object.entries(file.lines)
- .map(([line, messages]: [string, any]) => ({
- line: Number.parseInt(line),
- messages,
- }))
- .sort((a, b) => a.line - b.line), // Sort by line number
- }
- }),
- )
+ for (const diagnostic of diagnostics) {
+ const lines = grouped.get(diagnostic.filename) ?? new Map()
+ const line = diagnostic.labels?.[0]?.span?.line ?? 1
+ lines.set(line, [...(lines.get(line) ?? []), diagnostic])
+ grouped.set(diagnostic.filename, lines)
+ }
- return {
- files: result,
- summary: {
- number_of_files: data.number_of_files,
- number_of_rules: data.number_of_rules,
- threads_count: data.threads_count,
- start_time: data.start_time,
- files_with_issues: result.length,
- error_count: diagnostics.filter((d: any) => d.severity === 'error').length,
- warning_count: diagnostics.filter((d: any) => d.severity === 'warning').length,
- },
- }
- } catch (error) {
- console.error('Failed to parse oxlint output:', error)
- return { files: [], summary: {} }
+ const files: FileData[] = await Promise.all(
+ [...grouped].map(async ([filename, lines]) => ({
+ filename,
+ source: await readFile(resolve(root, filename), 'utf-8').catch(() => ''),
+ lines: [...lines].sort(([a], [b]) => a - b).map(([line, messages]) => ({ line, messages })),
+ })),
+ )
+ const summary: Summary = {
+ number_of_files: data.number_of_files as number,
+ number_of_rules: data.number_of_rules as number,
+ threads_count: data.threads_count as number,
+ start_time: data.start_time as number,
+ files_with_issues: files.length,
+ error_count: diagnostics.filter(diagnostic => diagnostic.severity === 'error').length,
+ warning_count: diagnostics.filter(diagnostic => diagnostic.severity === 'warning').length,
}
+
+ return { files, summary }
}
+
+export const clientDir = resolve(dirname(fileURLToPath(import.meta.url)), './client/public')
diff --git a/packages/oxc/src/nuxt.config.ts b/packages/oxc/src/nuxt.config.ts
index e5f85d62..4c218156 100644
--- a/packages/oxc/src/nuxt.config.ts
+++ b/packages/oxc/src/nuxt.config.ts
@@ -42,20 +42,17 @@ export default defineNuxtConfig({
},
app: {
baseURL: BASE,
- head: {
- title: 'Oxc Inspector',
+ head: {
+ title: 'Oxc DevTools',
+ charset: 'utf-8',
+ viewport: 'width=device-width,initial-scale=1',
meta: [
- {
- name: 'description',
- content: 'Inspect and understand the Oxc toolchain with ease.',
- },
+ { name: 'description', content: 'DevTools for Oxc' },
+ { property: 'og:title', content: 'Oxc DevTools' },
+ { property: 'og:description', content: 'DevTools for Oxc' },
],
link: [
- {
- rel: 'icon',
- type: 'image/svg+xml',
- href: '/favicon.svg',
- },
+ { rel: 'icon', type: 'image/svg+xml', href: `/favicon.svg` },
],
htmlAttrs: {
lang: 'en',
diff --git a/packages/oxc/src/types/index.ts b/packages/oxc/src/types/index.ts
index 646f519f..ff5d01ac 100644
--- a/packages/oxc/src/types/index.ts
+++ b/packages/oxc/src/types/index.ts
@@ -1,5 +1,6 @@
export interface Summary {
number_of_files: number
+ number_of_rules: number
threads_count: number
start_time: number
warning_count: number
@@ -7,7 +8,7 @@ export interface Summary {
files_with_issues: number
}
-export interface Meta {
+export interface LintResultMeta {
version: string
timestamp: number
summary: Summary
@@ -46,7 +47,7 @@ export interface FileData {
lines: LineData[]
}
-export interface Logs {
+export interface LintResultLogs {
files: FileData[]
config: object | null
}
diff --git a/packages/oxc/src/vite.ts b/packages/oxc/src/vite.ts
index 2256c673..bef9b934 100644
--- a/packages/oxc/src/vite.ts
+++ b/packages/oxc/src/vite.ts
@@ -2,6 +2,8 @@ import type { PluginWithDevTools } from '@vitejs/devtools-kit'
import { createPluginFromDevframe } from '@vitejs/devtools-kit/node'
import { DEVTOOLS_VITEPLUS_GROUP_ID } from '@vitejs/devtools-kit/constants'
import { oxcDevframe } from './node/devframe'
+import { enableOxlintRun } from './node/rpc/functions/oxlint-capabilities'
+import { viteRpcFunctions } from './node/rpc'
/**
* Mount the Oxc DevTools inside Vite DevTools. Delegates to kit's
@@ -14,5 +16,9 @@ export function DevToolsOxc(): PluginWithDevTools {
dock: {
groupId: DEVTOOLS_VITEPLUS_GROUP_ID,
},
+ setup(ctx) {
+ enableOxlintRun(ctx)
+ for (const fn of viteRpcFunctions) ctx.rpc.register(fn)
+ },
})
}
diff --git a/packages/oxc/tsconfig.json b/packages/oxc/tsconfig.json
deleted file mode 100644
index 99e6e8b5..00000000
--- a/packages/oxc/tsconfig.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "extends": "../../tsconfig.base.json",
- "compilerOptions": {
- "composite": true,
- "lib": ["esnext", "dom"]
- },
- "include": [
- "src/index.ts",
- "src/vite.ts",
- "src/dirs.ts",
- "src/commands",
- "src/node",
- "src/types",
- "bin"
- ]
-}
diff --git a/packages/ui/src/components/Panel/PanelSideNav.vue b/packages/ui/src/components/Panel/PanelSideNav.vue
index 33e917ca..acef9159 100644
--- a/packages/ui/src/components/Panel/PanelSideNav.vue
+++ b/packages/ui/src/components/Panel/PanelSideNav.vue
@@ -31,7 +31,7 @@ const items = computed(() => {
rounded-full
p2 hover:bg-active op-fade hover:op100
flex="~ items-center justify-center"
- exact-active-class="text-primary op100!"
+ active-class="text-primary op100!"
@click="item.action?.()"
>
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 77708dc7..48eeaf15 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -58,9 +58,6 @@ catalogs:
actionspack:
specifier: ^0.1.5
version: 0.1.5
- ansis:
- specifier: ^4.3.1
- version: 4.3.1
birpc:
specifier: ^4.0.0
version: 4.0.0
@@ -76,9 +73,6 @@ catalogs:
get-port-please:
specifier: ^3.2.0
version: 3.2.0
- gunshi:
- specifier: ^0.36.0
- version: 0.36.0
h3:
specifier: 2.0.1-rc.22
version: 2.0.1-rc.22
@@ -505,7 +499,7 @@ importers:
version: 3.2.4(@vitejs/devtools@0.3.4)(vite@8.1.4)(vue@3.5.39(typescript@6.0.3))
'@nuxt/eslint':
specifier: catalog:devtools
- version: 1.16.0(@typescript-eslint/utils@8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3))(@vue/compiler-sfc@3.5.39)(crossws@0.4.9(srvx@0.11.15))(esbuild@0.28.1)(eslint@10.7.0(jiti@2.7.0))(magicast@0.5.2)(oxc-parser@0.133.0)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))
+ version: 1.16.0(@typescript-eslint/utils@8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3))(@vue/compiler-sfc@3.5.39)(crossws@0.4.10(srvx@0.11.15))(esbuild@0.28.1)(eslint@10.7.0(jiti@2.7.0))(magicast@0.5.2)(oxc-parser@0.133.0)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))
'@nuxt/icon':
specifier: catalog:build
version: 2.3.1(magicast@0.5.2)(vite@8.1.4)(vue@3.5.39(typescript@6.0.3))
@@ -925,21 +919,15 @@ importers:
packages/oxc:
dependencies:
- '@clack/prompts':
- specifier: catalog:inlined
- version: 1.7.0
'@vitejs/devtools-kit':
specifier: workspace:*
version: link:../kit
- ansis:
- specifier: catalog:deps
- version: 4.3.1
+ cac:
+ specifier: ^7.0.0
+ version: 7.0.0
devframe:
specifier: catalog:deps
version: 0.7.2(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3)
- gunshi:
- specifier: catalog:deps
- version: 0.36.0
nostics:
specifier: catalog:deps
version: 1.1.4
@@ -6841,10 +6829,6 @@ packages:
resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==}
engines: {node: '>=6.0'}
- gunshi@0.36.0:
- resolution: {integrity: sha512-LJhM/2YiC4GfsaT2fnvccNkGXzbtMCBkgXpyLSM+1QVal2n7k8VJZol8qm1qgm2wmaQ6NBVmcGZIOkB/ms+6uQ==}
- engines: {node: '>= 22'}
-
gzip-size@6.0.0:
resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==}
engines: {node: '>=10'}
@@ -10090,10 +10074,10 @@ snapshots:
'@colordx/core@5.4.3': {}
- '@devframes/hub@0.5.4(devframe@0.5.4(crossws@0.4.9(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))':
+ '@devframes/hub@0.5.4(devframe@0.5.4(crossws@0.4.10(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))':
dependencies:
birpc: 4.0.0
- devframe: 0.5.4(crossws@0.4.9(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))
+ devframe: 0.5.4(crossws@0.4.10(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))
nostics: 0.2.0(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))
pathe: 2.0.3
perfect-debounce: 2.1.0
@@ -10405,12 +10389,12 @@ snapshots:
dependencies:
'@eslint/core': 1.2.1
- '@eslint/config-inspector@3.0.4(crossws@0.4.9(srvx@0.11.15))(esbuild@0.28.1)(eslint@10.7.0(jiti@2.7.0))(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))':
+ '@eslint/config-inspector@3.0.4(crossws@0.4.10(srvx@0.11.15))(esbuild@0.28.1)(eslint@10.7.0(jiti@2.7.0))(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))':
dependencies:
ansis: 4.3.1
cac: 7.0.0
chokidar: 5.0.0
- devframe: 0.5.4(crossws@0.4.9(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))
+ devframe: 0.5.4(crossws@0.4.10(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))
eslint: 10.7.0(jiti@2.7.0)
jiti: 2.7.0
tinyglobby: 0.2.17
@@ -10829,7 +10813,7 @@ snapshots:
which: 6.0.1
ws: 8.21.0
optionalDependencies:
- '@vitejs/devtools': 0.3.4(crossws@0.4.9(srvx@0.11.15))(db0@0.3.4)(esbuild@0.28.1)(idb-keyval@6.3.0)(ioredis@5.10.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))
+ '@vitejs/devtools': 0.3.4(crossws@0.4.10(srvx@0.11.15))(db0@0.3.4)(esbuild@0.28.1)(idb-keyval@6.3.0)(ioredis@5.10.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))
transitivePeerDependencies:
- bufferutil
- supports-color
@@ -10919,9 +10903,9 @@ snapshots:
- supports-color
- typescript
- '@nuxt/eslint@1.16.0(@typescript-eslint/utils@8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3))(@vue/compiler-sfc@3.5.39)(crossws@0.4.9(srvx@0.11.15))(esbuild@0.28.1)(eslint@10.7.0(jiti@2.7.0))(magicast@0.5.2)(oxc-parser@0.133.0)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))':
+ '@nuxt/eslint@1.16.0(@typescript-eslint/utils@8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3))(@vue/compiler-sfc@3.5.39)(crossws@0.4.10(srvx@0.11.15))(esbuild@0.28.1)(eslint@10.7.0(jiti@2.7.0))(magicast@0.5.2)(oxc-parser@0.133.0)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))':
dependencies:
- '@eslint/config-inspector': 3.0.4(crossws@0.4.9(srvx@0.11.15))(esbuild@0.28.1)(eslint@10.7.0(jiti@2.7.0))(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))
+ '@eslint/config-inspector': 3.0.4(crossws@0.4.10(srvx@0.11.15))(esbuild@0.28.1)(eslint@10.7.0(jiti@2.7.0))(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))
'@nuxt/devtools-kit': 3.2.4(magicast@0.5.2)(vite@8.1.4)
'@nuxt/eslint-config': 1.16.0(@typescript-eslint/utils@8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3))(@vue/compiler-sfc@3.5.39)(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3)
'@nuxt/eslint-plugin': 1.16.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3)
@@ -13362,11 +13346,11 @@ snapshots:
- rollup
- supports-color
- '@vitejs/devtools-kit@0.3.4(crossws@0.4.9(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))':
+ '@vitejs/devtools-kit@0.3.4(crossws@0.4.10(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))':
dependencies:
- '@devframes/hub': 0.5.4(devframe@0.5.4(crossws@0.4.9(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))
+ '@devframes/hub': 0.5.4(devframe@0.5.4(crossws@0.4.10(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))
birpc: 4.0.0
- devframe: 0.5.4(crossws@0.4.9(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))
+ devframe: 0.5.4(crossws@0.4.10(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))
mlly: 1.8.2
nostics: 1.1.4
pathe: 2.0.3
@@ -13401,18 +13385,18 @@ snapshots:
- srvx
- typescript
- '@vitejs/devtools-rolldown@0.3.4(crossws@0.4.9(srvx@0.11.15))(db0@0.3.4)(esbuild@0.28.1)(idb-keyval@6.3.0)(ioredis@5.10.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(vue@3.5.39(typescript@6.0.3))(webpack@5.104.1(esbuild@0.28.1))':
+ '@vitejs/devtools-rolldown@0.3.4(crossws@0.4.10(srvx@0.11.15))(db0@0.3.4)(esbuild@0.28.1)(idb-keyval@6.3.0)(ioredis@5.10.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(vue@3.5.39(typescript@6.0.3))(webpack@5.104.1(esbuild@0.28.1))':
dependencies:
'@floating-ui/dom': 1.8.0
'@rolldown/debug': 1.1.5
- '@vitejs/devtools-kit': 0.3.4(crossws@0.4.9(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))
+ '@vitejs/devtools-kit': 0.3.4(crossws@0.4.10(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))
birpc: 4.0.0
cac: 7.0.0
d3-shape: 3.2.0
- devframe: 0.5.4(crossws@0.4.9(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))
+ devframe: 0.5.4(crossws@0.4.10(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))
diff: 9.0.0
get-port-please: 3.2.0
- h3: 2.0.1-rc.22(crossws@0.4.9(srvx@0.11.15))
+ h3: 2.0.1-rc.22(crossws@0.4.10(srvx@0.11.15))
mlly: 1.8.2
mrmime: 2.0.1
nostics: 1.1.4
@@ -13479,15 +13463,15 @@ snapshots:
- vue
optional: true
- '@vitejs/devtools@0.3.4(crossws@0.4.9(srvx@0.11.15))(db0@0.3.4)(esbuild@0.28.1)(idb-keyval@6.3.0)(ioredis@5.10.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))':
+ '@vitejs/devtools@0.3.4(crossws@0.4.10(srvx@0.11.15))(db0@0.3.4)(esbuild@0.28.1)(idb-keyval@6.3.0)(ioredis@5.10.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))':
dependencies:
- '@devframes/hub': 0.5.4(devframe@0.5.4(crossws@0.4.9(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))
- '@vitejs/devtools-kit': 0.3.4(crossws@0.4.9(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))
- '@vitejs/devtools-rolldown': 0.3.4(crossws@0.4.9(srvx@0.11.15))(db0@0.3.4)(esbuild@0.28.1)(idb-keyval@6.3.0)(ioredis@5.10.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(vue@3.5.39(typescript@6.0.3))(webpack@5.104.1(esbuild@0.28.1))
+ '@devframes/hub': 0.5.4(devframe@0.5.4(crossws@0.4.10(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))
+ '@vitejs/devtools-kit': 0.3.4(crossws@0.4.10(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))
+ '@vitejs/devtools-rolldown': 0.3.4(crossws@0.4.10(srvx@0.11.15))(db0@0.3.4)(esbuild@0.28.1)(idb-keyval@6.3.0)(ioredis@5.10.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(vue@3.5.39(typescript@6.0.3))(webpack@5.104.1(esbuild@0.28.1))
birpc: 4.0.0
cac: 7.0.0
- devframe: 0.5.4(crossws@0.4.9(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))
- h3: 2.0.1-rc.22(crossws@0.4.9(srvx@0.11.15))
+ devframe: 0.5.4(crossws@0.4.10(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))
+ h3: 2.0.1-rc.22(crossws@0.4.10(srvx@0.11.15))
mlly: 1.8.2
nostics: 1.1.4
obug: 2.1.3
@@ -14900,12 +14884,12 @@ snapshots:
devalue@5.8.1: {}
- devframe@0.5.4(crossws@0.4.9(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)):
+ devframe@0.5.4(crossws@0.4.10(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)):
dependencies:
'@valibot/to-json-schema': 1.7.1(valibot@1.4.2(typescript@6.0.3))
birpc: 4.0.0
cac: 7.0.0
- h3: 2.0.1-rc.22(crossws@0.4.9(srvx@0.11.15))
+ h3: 2.0.1-rc.22(crossws@0.4.10(srvx@0.11.15))
mrmime: 2.0.1
nostics: 0.2.0(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))
pathe: 2.0.3
@@ -15708,8 +15692,6 @@ snapshots:
section-matter: 1.0.0
strip-bom-string: 1.0.0
- gunshi@0.36.0: {}
-
gzip-size@6.0.0:
dependencies:
duplexer: 0.1.2
@@ -15737,13 +15719,6 @@ snapshots:
optionalDependencies:
crossws: 0.4.10(srvx@0.11.15)
- h3@2.0.1-rc.22(crossws@0.4.9(srvx@0.11.15)):
- dependencies:
- rou3: 0.8.1
- srvx: 0.11.15
- optionalDependencies:
- crossws: 0.4.9(srvx@0.11.15)
-
hachure-fill@0.5.2: {}
has-flag@4.0.0: {}
@@ -18770,7 +18745,7 @@ snapshots:
tree-kill: 1.2.2
unconfig-core: 7.5.0
optionalDependencies:
- '@vitejs/devtools': 0.3.4(crossws@0.4.9(srvx@0.11.15))(db0@0.3.4)(esbuild@0.28.1)(idb-keyval@6.3.0)(ioredis@5.10.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))
+ '@vitejs/devtools': 0.3.4(crossws@0.4.10(srvx@0.11.15))(db0@0.3.4)(esbuild@0.28.1)(idb-keyval@6.3.0)(ioredis@5.10.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))
publint: 0.3.21
tsx: 4.23.1
typescript: 6.0.3
@@ -19456,7 +19431,7 @@ snapshots:
tinyglobby: 0.2.17
optionalDependencies:
'@types/node': 25.0.3
- '@vitejs/devtools': 0.3.4(crossws@0.4.9(srvx@0.11.15))(db0@0.3.4)(esbuild@0.28.1)(idb-keyval@6.3.0)(ioredis@5.10.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))
+ '@vitejs/devtools': 0.3.4(crossws@0.4.10(srvx@0.11.15))(db0@0.3.4)(esbuild@0.28.1)(idb-keyval@6.3.0)(ioredis@5.10.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))
esbuild: 0.28.1
fsevents: 2.3.3
jiti: 2.7.0
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
index dd0bdc3a..4e52f7b1 100644
--- a/pnpm-workspace.yaml
+++ b/pnpm-workspace.yaml
@@ -65,14 +65,12 @@ catalogs:
'@devframes/plugin-terminals': ^0.7.2
'@rolldown/debug': ^1.1.5
actionspack: ^0.1.5
- ansis: ^4.3.1
birpc: ^4.0.0
cac: ^7.0.0
devframe: ^0.7.2
diff: ^9.0.0
envinfo: ^7.21.0
get-port-please: ^3.2.0
- gunshi: ^0.36.0
h3: 2.0.1-rc.22
local-pkg: ^1.2.1
mlly: ^1.8.2