diff --git a/AGENTS.md b/AGENTS.md index cebc1835..d31c2acc 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -93,7 +93,7 @@ The kit is the integration hub. When adding to it, the question is "does this he ## Structured Diagnostics (Error Codes) -All node-side warnings and errors use structured diagnostics via [`logs-sdk`](https://github.com/vercel-labs/logs-sdk). Never use raw `console.warn`, `console.error`, or `throw new Error` with ad-hoc messages in node-side code — always define a coded diagnostic. +All node-side warnings and errors use structured diagnostics via [`nostics`](https://github.com/vercel-labs/nostics). Never use raw `console.warn`, `console.error`, or `throw new Error` with ad-hoc messages in node-side code — always define a coded diagnostic. ### Code prefixes @@ -115,23 +115,21 @@ Codes are sequential 4-digit numbers per prefix (e.g. `DTK0033`, `RDDT0003`). Ch ```txt // diagnostics.ts DTK0033: { - message: (p: { name: string }) => `Something went wrong with "${p.name}"`, - hint: 'Optional hint for the user.', - level: 'warn', // defaults to 'error' if omitted + why: (p: { name: string }) => `Something went wrong with "${p.name}"`, + fix: 'Optional remediation hint for the user.', }, ``` -2. **Use the logger** at the call site: +2. **Emit the diagnostic** at the call site: ```ts - import { logger } from './diagnostics' + import { diagnostics } from './diagnostics' // For thrown errors — always prefix with `throw` for TypeScript control flow: - throw logger.DTK0033({ name }).throw() + throw diagnostics.DTK0033.throw({ name }) - // For logged warnings/errors (not thrown): - logger.DTK0033({ name }).log() // uses definition level - logger.DTK0033({ name }).warn() // override to warn - logger.DTK0033({ name }, { cause: error }).log() // attach cause + // For reported (non-thrown) diagnostics: + diagnostics.DTK0033.report({ name }) + diagnostics.DTK0033.report({ name, cause: error }) // attach cause via params ``` 3. **Create a docs page** at `docs/errors/DTK0033.md`: diff --git a/devframe b/devframe index 2458e6e5..6f75d5c6 160000 --- a/devframe +++ b/devframe @@ -1 +1 @@ -Subproject commit 2458e6e5fe79bff0e6a9736fe63fc4059b2e68e5 +Subproject commit 6f75d5c65bdf9690a53402b5301650c47d960584 diff --git a/docs/errors/index.md b/docs/errors/index.md index 4be298bb..54660d62 100644 --- a/docs/errors/index.md +++ b/docs/errors/index.md @@ -11,7 +11,7 @@ Vite DevTools uses structured diagnostics to surface actionable warnings and err - Codes follow the pattern **prefix + 4-digit number** (e.g., `DF0001`, `DTK0008`, `RDDT0002`). - Each prefix maps to a package: `DTK` for `@vitejs/devtools` (Vite-specific pieces), `RDDT` for `@vitejs/devtools-rolldown`. The framework-neutral `devframe` package documents its own `DF`-prefixed codes at the [Devframe docs site](https://devfra.me/errors/). - Every error page includes the cause, recommended fix, and a reference to the source file that emits it. -- The diagnostics system is powered by [`logs-sdk`](https://github.com/vercel-labs/logs-sdk), which provides structured logging with docs URLs, ANSI-formatted console output, and level-based filtering. +- The diagnostics system is powered by [`nostics`](https://github.com/vercel-labs/nostics), which provides structured diagnostic codes with docs URLs and ANSI-formatted console output. ## DevTools Kit (DTK) diff --git a/docs/kit/diagnostics.md b/docs/kit/diagnostics.md index e3e68c11..ee3693b7 100644 --- a/docs/kit/diagnostics.md +++ b/docs/kit/diagnostics.md @@ -1,6 +1,6 @@ # Structured Diagnostics -`ctx.diagnostics` is a thin layer over [`logs-sdk`](https://github.com/vercel-labs/logs-sdk) that lets DevTools plugins register coded errors and warnings into a shared logger without depending on `logs-sdk` directly. Use it for author-defined coded diagnostics — errors, warnings, deprecations — that carry a stable code, a documentation URL, and a structured payload. For free-form runtime output that should appear in the DevTools UI, use [`ctx.messages`](./messages). +`ctx.diagnostics` is a thin layer over [`nostics`](https://github.com/vercel-labs/nostics) that lets DevTools plugins register coded errors and warnings into a shared registry without depending on `nostics` directly. Use it for author-defined coded diagnostics — errors, warnings, deprecations — that carry a stable code, a documentation URL, and a structured payload. For free-form runtime output that should appear in the DevTools UI, use [`ctx.messages`](./messages). | Surface | Purpose | Example | |---------|---------|---------| @@ -11,17 +11,20 @@ ```ts interface DevToolsDiagnosticsHost { - /** Combined logs-sdk Logger across all registered diagnostics. */ - readonly logger: Logger + /** + * Proxy-backed lookup of every registered code by name. Each entry is a + * `nostics` handle with `.report()` and `.throw()` methods. + */ + readonly logger: Record /** Register additional diagnostic definitions. */ - register: (definitions: DiagnosticsResult) => void + register: (definitions: Record) => void - /** Re-export of logs-sdk's `defineDiagnostics`. */ + /** + * Mirror of `nostics`'s `defineDiagnostics`, pre-wired with the host's + * ANSI console reporter — plugins typically omit `reporters`. + */ defineDiagnostics: typeof defineDiagnostics - - /** Re-export of logs-sdk's `createLogger`. */ - createLogger: typeof createLogger } ``` @@ -41,20 +44,19 @@ export function MyPlugin(): PluginWithDevTools { docsBase: 'https://example.com/errors', codes: { MYP0001: { - message: (p: { name: string }) => `Plugin "${p.name}" is not configured`, - hint: 'Add the plugin to your `vite.config.ts` and pass an options object.', + why: (p: { name: string }) => `Plugin "${p.name}" is not configured`, + fix: 'Add the plugin to your `vite.config.ts` and pass an options object.', }, MYP0002: { - message: 'Cache directory missing — running cold.', - level: 'warn', + why: 'Cache directory missing — running cold.', }, }, }) ctx.diagnostics.register(diagnostics) - // Now you can emit codes through the shared logger: - ctx.diagnostics.logger.MYP0002().log() + // Emit codes through the shared lookup: + ctx.diagnostics.logger.MYP0002.report() }, }, } @@ -74,68 +76,49 @@ Prefixes used by the in-tree packages: | `RDDT` | `@vitejs/devtools-rolldown` | | `VDT` | `@vitejs/devtools-vite` (reserved) | -Each definition supports `message` (string or function), optional `hint`, optional `level` (`'error'` / `'warn'` / `'suggestion'` / `'deprecation'` — defaults to `'error'`), and a `docsBase` for generating documentation URLs. +Each definition supports `why` (string or function returning a string) and an optional `fix` (string or function). A `docsBase` on the definition group auto-attaches a per-code URL to every emitted diagnostic. ## Emit a diagnostic -Each registered code becomes a callable factory on `ctx.diagnostics.logger`. The factory returns an object with `.throw()`, `.warn()`, `.error()`, `.log()`, and `.format()`. +Each registered code is reachable as a property on `ctx.diagnostics.logger`. Every handle exposes `.throw(params)` and `.report(params)`. ```ts // Throw — control flow stops here -throw ctx.diagnostics.logger.MYP0001({ name: 'foo' }).throw() - -// Log without throwing -ctx.diagnostics.logger.MYP0002().log() +throw ctx.diagnostics.logger.MYP0001.throw({ name: 'foo' }) -// Override level per call -ctx.diagnostics.logger.MYP0002().warn() +// Report without throwing (goes through the host's reporter) +ctx.diagnostics.logger.MYP0002.report() -// Attach a `cause` -ctx.diagnostics.logger.MYP0001({ name: 'foo' }, { cause: error }).log() +// Attach a `cause` via the params object +ctx.diagnostics.logger.MYP0001.report({ name: 'foo', cause: error }) ``` `.throw()` is typed `never`. Prefix the call with `throw` so TypeScript narrows control flow correctly: ```ts -throw ctx.diagnostics.logger.MYP0001({ name }).throw() +throw ctx.diagnostics.logger.MYP0001.throw({ name }) ``` -## Typed logger reference +## Typed handle reference -`ctx.diagnostics.logger` is loosely typed — it covers an unbounded set of registered codes, beyond what TypeScript can narrow. For autocompletion on your plugin's specific codes, keep a typed reference returned from `createLogger`: +`ctx.diagnostics.logger` is a loosely typed proxy — it covers an unbounded set of registered codes, beyond what TypeScript can narrow. For autocompletion on your plugin's specific codes, keep a reference to the typed handle returned by `defineDiagnostics()`: ```ts const myDiagnostics = ctx.diagnostics.defineDiagnostics({ docsBase: 'https://example.com/errors', codes: { - MYP0001: { message: (p: { name: string }) => `…${p.name}` }, + MYP0001: { why: (p: { name: string }) => `…${p.name}` }, }, }) -// Register so the shared logger can also see it +// Register so the shared lookup can also see it ctx.diagnostics.register(myDiagnostics) -// Keep a typed reference for your own emit sites -const logger = ctx.diagnostics.createLogger({ diagnostics: [myDiagnostics] }) -logger.MYP0001({ name: 'foo' }).warn() -``` - -Both loggers share the formatter and reporter defaults set by the host (ANSI console output). - -## Don't cache the combined logger - -`ctx.diagnostics.logger` is a getter — it returns the freshest combined logger, rebuilt each time `register()` is called. Don't cache it across registrations: - -```ts -// ❌ Stale after a later register() call -const log = ctx.diagnostics.logger -log.MYP0001({ name: 'foo' }).log() - -// ✅ Always fresh -ctx.diagnostics.logger.MYP0001({ name: 'foo' }).log() +// Use the typed handle directly at emit sites +myDiagnostics.MYP0001.report({ name: 'foo' }) ``` -For a stable reference, use the typed `createLogger` form above. +Both paths share the formatter and reporter defaults set by the host (ANSI console output). ## Document your codes diff --git a/package.json b/package.json index 3be6e9b0..0d1f3d51 100644 --- a/package.json +++ b/package.json @@ -61,9 +61,9 @@ "chokidar": "catalog:devtools", "esbuild": "catalog:build", "eslint": "catalog:devtools", - "logs-sdk": "catalog:deps", "magic-string": "catalog:build", "nano-staged": "catalog:devtools", + "nostics": "catalog:deps", "nuxt": "catalog:build", "p-limit": "catalog:deps", "pathe": "catalog:deps", diff --git a/packages/core/package.json b/packages/core/package.json index 857174c0..5b715762 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -62,8 +62,8 @@ "cac": "catalog:deps", "devframe": "catalog:deps", "h3": "catalog:deps", - "logs-sdk": "catalog:deps", "mlly": "catalog:deps", + "nostics": "catalog:deps", "obug": "catalog:deps", "pathe": "catalog:deps", "perfect-debounce": "catalog:deps", diff --git a/packages/core/src/node/cli-commands.ts b/packages/core/src/node/cli-commands.ts index a2adc5af..fa51f285 100644 --- a/packages/core/src/node/cli-commands.ts +++ b/packages/core/src/node/cli-commands.ts @@ -8,7 +8,7 @@ import { colors as c } from 'devframe/utils/colors' import { open } from 'devframe/utils/open' import { resolve } from 'pathe' import { MARK_NODE } from './constants' -import { logger } from './diagnostics' +import { diagnostics } from './diagnostics' export interface StartOptions { root?: string @@ -88,5 +88,5 @@ export async function build(options: BuildOptions) { outDir, }) - logger.DTK0010().log() + diagnostics.DTK0010.report() } diff --git a/packages/core/src/node/context.ts b/packages/core/src/node/context.ts index c6b4e421..f28f1ed1 100644 --- a/packages/core/src/node/context.ts +++ b/packages/core/src/node/context.ts @@ -4,7 +4,7 @@ import type { ResolvedConfig, ViteDevServer } from 'vite' import { createKitContext, createViteDevToolsHost } from '@vitejs/devtools-kit/node' import { isObject } from 'devframe/node' import { createDebug } from 'obug' -import { diagnostics, logger } from './diagnostics' +import { diagnostics } from './diagnostics' import { builtinRpcDeclarations } from './rpc' const debugSetup = createDebug('vite:devtools:context:setup') @@ -78,7 +78,7 @@ export async function createDevToolsContext( await plugin.devtools?.setup?.(context) } catch (error) { - throw logger.DTK0014({ name: plugin.name }, { cause: error }).throw() + throw diagnostics.DTK0014.throw({ name: plugin.name, cause: error }) } } diff --git a/packages/core/src/node/diagnostics.ts b/packages/core/src/node/diagnostics.ts index 7045f721..72979117 100644 --- a/packages/core/src/node/diagnostics.ts +++ b/packages/core/src/node/diagnostics.ts @@ -1,53 +1,44 @@ -import { colors as c } from 'devframe/utils/colors' -import { consoleReporter, createLogger, defineDiagnostics } from 'logs-sdk' -import { ansiFormatter } from 'logs-sdk/formatters/ansi' +import { defineDiagnostics, reporterLog } from 'nostics' export const diagnostics = defineDiagnostics({ docsBase: 'https://devtools.vite.dev/errors', + reporters: [reporterLog], codes: { DTK0008: { - message: 'Client authentication is disabled. Any browser can connect to the devtools and access your server and filesystem.', - level: 'warn', + why: 'Client authentication is disabled. Any browser can connect to the devtools and access your server and filesystem.', }, DTK0010: { - message: 'Static build is still experimental and not yet complete. Generated output may be missing features and can change without notice.', - level: 'warn', + why: 'Static build is still experimental and not yet complete. Generated output may be missing features and can change without notice.', }, DTK0011: { - message: (p: { name: string }) => `RPC error on executing "${p.name}"`, + why: (p: { name: string }) => `RPC error on executing "${p.name}"`, }, DTK0012: { - message: 'RPC error on executing rpc', + why: 'RPC error on executing rpc', }, DTK0013: { - message: (p: { name: string, clientId: string }) => `Unauthorized access to method ${JSON.stringify(p.name)} from client [${p.clientId}]`, + why: (p: { name: string, clientId: string }) => `Unauthorized access to method ${JSON.stringify(p.name)} from client [${p.clientId}]`, }, DTK0014: { - message: (p: { name: string }) => `Error setting up plugin ${p.name}`, + why: (p: { name: string }) => `Error setting up plugin ${p.name}`, }, DTK0023: { - message: 'viteServer is required in dev mode', + why: 'viteServer is required in dev mode', }, DTK0028: { - message: 'Path is outside the workspace root', + why: 'Path is outside the workspace root', }, DTK0029: { - message: 'Path is outside the workspace root', + why: 'Path is outside the workspace root', }, DTK0030: { - message: (p: { id: string }) => `Dock entry with id "${p.id}" not found`, + why: (p: { id: string }) => `Dock entry with id "${p.id}" not found`, }, DTK0031: { - message: (p: { id: string }) => `Dock entry with id "${p.id}" is not a launcher`, + why: (p: { id: string }) => `Dock entry with id "${p.id}" is not a launcher`, }, DTK0032: { - message: (p: { id: string }) => `Error launching dock entry "${p.id}"`, + why: (p: { id: string }) => `Error launching dock entry "${p.id}"`, }, }, }) - -export const logger = createLogger({ - diagnostics: [diagnostics], - formatter: ansiFormatter(c), - reporters: consoleReporter, -}) diff --git a/packages/core/src/node/rpc/internal/docks-on-launch.ts b/packages/core/src/node/rpc/internal/docks-on-launch.ts index 3376d03a..d4df3538 100644 --- a/packages/core/src/node/rpc/internal/docks-on-launch.ts +++ b/packages/core/src/node/rpc/internal/docks-on-launch.ts @@ -1,5 +1,5 @@ import { defineRpcFunction } from '@vitejs/devtools-kit' -import { logger } from '../../diagnostics' +import { diagnostics } from '../../diagnostics' export const docksOnLaunch = defineRpcFunction({ name: 'devtoolskit:internal:docks:on-launch', @@ -14,10 +14,10 @@ export const docksOnLaunch = defineRpcFunction({ const entry = context.docks.values().find(entry => entry.id === entryId) if (!entry) { - throw logger.DTK0030({ id: entryId }).throw() + throw diagnostics.DTK0030.throw({ id: entryId }) } if (entry.type !== 'launcher') { - throw logger.DTK0031({ id: entryId }).throw() + throw diagnostics.DTK0031.throw({ id: entryId }) } try { context.docks.update({ @@ -43,7 +43,7 @@ export const docksOnLaunch = defineRpcFunction({ return result } catch (error) { - logger.DTK0032({ id: entryId }, { cause: error }).log() + diagnostics.DTK0032.report({ id: entryId, cause: error }) context.docks.update({ ...entry, launcher: { diff --git a/packages/core/src/node/rpc/public/open-in-editor.ts b/packages/core/src/node/rpc/public/open-in-editor.ts index dd2fd028..d728f785 100644 --- a/packages/core/src/node/rpc/public/open-in-editor.ts +++ b/packages/core/src/node/rpc/public/open-in-editor.ts @@ -1,7 +1,7 @@ import { relative, resolve } from 'node:path' import { defineRpcFunction } from '@vitejs/devtools-kit' import { launchEditor } from 'devframe/utils/launch-editor' -import { logger } from '../../diagnostics' +import { diagnostics } from '../../diagnostics' export const openInEditor = defineRpcFunction({ name: 'vite:core:open-in-editor', @@ -15,7 +15,7 @@ export const openInEditor = defineRpcFunction({ // Prevent escaping the workspace root if (rel.startsWith('..') || rel.includes('\0')) { - throw logger.DTK0028().throw() + throw diagnostics.DTK0028.throw() } launchEditor(resolved) diff --git a/packages/core/src/node/rpc/public/open-in-finder.ts b/packages/core/src/node/rpc/public/open-in-finder.ts index 4eb19b09..7ad4ce91 100644 --- a/packages/core/src/node/rpc/public/open-in-finder.ts +++ b/packages/core/src/node/rpc/public/open-in-finder.ts @@ -1,7 +1,7 @@ import { relative, resolve } from 'node:path' import { defineRpcFunction } from '@vitejs/devtools-kit' import { open } from 'devframe/utils/open' -import { logger } from '../../diagnostics' +import { diagnostics } from '../../diagnostics' export const openInFinder = defineRpcFunction({ name: 'vite:core:open-in-finder', @@ -15,7 +15,7 @@ export const openInFinder = defineRpcFunction({ // Ensure the path stays within workspace root if (rel.startsWith('..') || rel.includes('\0')) { - throw logger.DTK0029().throw() + throw diagnostics.DTK0029.throw() } await open(resolved) diff --git a/packages/core/src/node/ws.ts b/packages/core/src/node/ws.ts index f52ee145..43ee4563 100644 --- a/packages/core/src/node/ws.ts +++ b/packages/core/src/node/ws.ts @@ -11,7 +11,7 @@ import { colors as c } from 'devframe/utils/colors' import { getPort } from 'get-port-please' import { createDebug } from 'obug' import { MARK_INFO } from './constants' -import { logger } from './diagnostics' +import { diagnostics } from './diagnostics' const debugInvoked = createDebug('vite:devtools:rpc:invoked') @@ -50,7 +50,7 @@ export async function createWsServer(options: CreateWsServerOptions) { const isClientAuthDisabled = context.mode === 'build' || context.viteConfig.devtools?.config?.clientAuth === false || process.env.VITE_DEVTOOLS_DISABLE_CLIENT_AUTH === 'true' if (isClientAuthDisabled) { - logger.DTK0008().log() + diagnostics.DTK0008.report() } contextInternal.wsEndpoint = { @@ -74,10 +74,10 @@ export async function createWsServer(options: CreateWsServerOptions) { { rpcOptions: { onFunctionError(error, name) { - logger.DTK0011({ name }, { cause: error }).log() + diagnostics.DTK0011.report({ name, cause: error }) }, onGeneralError(error) { - logger.DTK0012({ cause: error }).log() + diagnostics.DTK0012.report({ cause: error }) }, resolver(name, fn) { // eslint-disable-next-line ts/no-this-alias @@ -86,7 +86,7 @@ export async function createWsServer(options: CreateWsServerOptions) { // Block unauthorized access to non-anonymous methods if (!name.startsWith(ANONYMOUS_SCOPE) && !rpc.$meta.isTrusted) { return () => { - throw logger.DTK0013({ name, clientId: rpc.$meta.id }).throw() + throw diagnostics.DTK0013.throw({ name, clientId: rpc.$meta.id }) } } diff --git a/packages/kit/package.json b/packages/kit/package.json index 74a505ae..56c594d8 100644 --- a/packages/kit/package.json +++ b/packages/kit/package.json @@ -46,8 +46,8 @@ "dependencies": { "birpc": "catalog:deps", "devframe": "catalog:deps", - "logs-sdk": "catalog:deps", "mlly": "catalog:deps", + "nostics": "catalog:deps", "pathe": "catalog:deps", "perfect-debounce": "catalog:deps", "tinyexec": "catalog:deps" diff --git a/packages/kit/src/node/diagnostics.ts b/packages/kit/src/node/diagnostics.ts index 4631cd66..42e3f49f 100644 --- a/packages/kit/src/node/diagnostics.ts +++ b/packages/kit/src/node/diagnostics.ts @@ -1,6 +1,4 @@ -import { colors as c } from 'devframe/utils/colors' -import { consoleReporter, createLogger, defineDiagnostics } from 'logs-sdk' -import { ansiFormatter } from 'logs-sdk/formatters/ansi' +import { defineDiagnostics, reporterLog } from 'nostics' // Kit-side diagnostics for the hub subsystems (docks, terminals, commands, // messages). The `DTK` prefix is shared with `@vitejs/devtools` (core); @@ -8,37 +6,32 @@ import { ansiFormatter } from 'logs-sdk/formatters/ansi' // below that today. export const diagnostics = defineDiagnostics({ docsBase: 'https://devtools.vite.dev/errors', + reporters: [reporterLog], codes: { DTK0050: { - message: (p: { id: string }) => `Dock with id "${p.id}" is already registered`, - hint: 'Use the `force` parameter to overwrite an existing registration.', + why: (p: { id: string }) => `Dock with id "${p.id}" is already registered`, + fix: 'Use the `force` parameter to overwrite an existing registration.', }, DTK0051: { - message: 'Cannot change the id of a dock. Use register() to add new docks.', + why: 'Cannot change the id of a dock. Use register() to add new docks.', }, DTK0052: { - message: (p: { id: string }) => `Dock with id "${p.id}" is not registered. Use register() to add new docks.`, + why: (p: { id: string }) => `Dock with id "${p.id}" is not registered. Use register() to add new docks.`, }, DTK0053: { - message: (p: { id: string }) => `Terminal session with id "${p.id}" already registered`, + why: (p: { id: string }) => `Terminal session with id "${p.id}" already registered`, }, DTK0054: { - message: (p: { id: string }) => `Terminal session with id "${p.id}" not registered`, + why: (p: { id: string }) => `Terminal session with id "${p.id}" not registered`, }, DTK0055: { - message: (p: { id: string }) => `Command "${p.id}" is already registered`, + why: (p: { id: string }) => `Command "${p.id}" is already registered`, }, DTK0056: { - message: 'Cannot change the id of a command. Use register() to add new commands.', + why: 'Cannot change the id of a command. Use register() to add new commands.', }, DTK0057: { - message: (p: { id: string }) => `Command "${p.id}" is not registered`, + why: (p: { id: string }) => `Command "${p.id}" is not registered`, }, }, }) - -export const logger = createLogger({ - diagnostics: [diagnostics], - formatter: ansiFormatter(c), - reporters: consoleReporter, -}) diff --git a/packages/kit/src/node/host-commands.ts b/packages/kit/src/node/host-commands.ts index bc77e30b..dbcad21b 100644 --- a/packages/kit/src/node/host-commands.ts +++ b/packages/kit/src/node/host-commands.ts @@ -6,7 +6,7 @@ import type { } from '../types/commands' import type { KitNodeContext } from './context' import { createEventEmitter } from 'devframe/utils/events' -import { logger } from './diagnostics' +import { diagnostics } from './diagnostics' export class DevToolsCommandsHost implements DevToolsCommandsHostType { public readonly commands: DevToolsCommandsHostType['commands'] = new Map() @@ -18,7 +18,7 @@ export class DevToolsCommandsHost implements DevToolsCommandsHostType { register(command: DevToolsServerCommandInput): DevToolsCommandHandle { if (this.commands.has(command.id)) { - throw logger.DTK0055({ id: command.id }).throw() + throw diagnostics.DTK0055.throw({ id: command.id }) } this.commands.set(command.id, command) this.events.emit('command:registered', this.toSerializable(command)) @@ -27,11 +27,11 @@ export class DevToolsCommandsHost implements DevToolsCommandsHostType { id: command.id, update: (patch: Partial>) => { if ('id' in patch) { - throw logger.DTK0056().throw() + throw diagnostics.DTK0056.throw() } const existing = this.commands.get(command.id) if (!existing) { - throw logger.DTK0057({ id: command.id }).throw() + throw diagnostics.DTK0057.throw({ id: command.id }) } Object.assign(existing, patch) this.events.emit('command:registered', this.toSerializable(existing)) @@ -51,7 +51,7 @@ export class DevToolsCommandsHost implements DevToolsCommandsHostType { async execute(id: string, ...args: any[]): Promise { const found = this.findCommand(id) if (!found) { - throw logger.DTK0057({ id }).throw() + throw diagnostics.DTK0057.throw({ id }) } if (!found.handler) { throw new Error(`Command "${id}" has no handler (group-only command)`) diff --git a/packages/kit/src/node/host-docks.ts b/packages/kit/src/node/host-docks.ts index b0ef88a7..a90f714a 100644 --- a/packages/kit/src/node/host-docks.ts +++ b/packages/kit/src/node/host-docks.ts @@ -17,7 +17,7 @@ import { getInternalContext } from 'devframe/node/internal' import { createEventEmitter } from 'devframe/utils/events' import { join } from 'pathe' import { DEFAULT_STATE_USER_SETTINGS } from '../constants' -import { logger } from './diagnostics' +import { diagnostics } from './diagnostics' interface RemoteDockRecord { token: string @@ -157,7 +157,7 @@ export class DevToolsDockHost implements DevToolsDockHostType { update: (patch: Partial) => void } { if (this.views.has(view.id) && !force) { - throw logger.DTK0050({ id: view.id }).throw() + throw diagnostics.DTK0050.throw({ id: view.id }) } this.prepareRemoteRegistration(view) this.views.set(view.id, view) @@ -166,7 +166,7 @@ export class DevToolsDockHost implements DevToolsDockHostType { return { update: (patch) => { if (patch.id && patch.id !== view.id) { - throw logger.DTK0051().throw() + throw diagnostics.DTK0051.throw() } this.update(Object.assign(this.views.get(view.id)!, patch)) }, @@ -175,7 +175,7 @@ export class DevToolsDockHost implements DevToolsDockHostType { update(view: DevToolsDockUserEntry): void { if (!this.views.has(view.id)) { - throw logger.DTK0052({ id: view.id }).throw() + throw diagnostics.DTK0052.throw({ id: view.id }) } this.prepareRemoteRegistration(view) this.views.set(view.id, view) diff --git a/packages/kit/src/node/host-terminals.ts b/packages/kit/src/node/host-terminals.ts index f7e36821..5a69556f 100644 --- a/packages/kit/src/node/host-terminals.ts +++ b/packages/kit/src/node/host-terminals.ts @@ -10,7 +10,7 @@ import type { import type { KitNodeContext } from './context' import process from 'node:process' import { createEventEmitter } from 'devframe/utils/events' -import { logger } from './diagnostics' +import { diagnostics } from './diagnostics' type PartialWithoutId = Partial & { id: string } @@ -57,7 +57,7 @@ export class DevToolsTerminalHost implements DevToolsTerminalHostType { register(session: DevToolsTerminalSession): DevToolsTerminalSession { if (this.sessions.has(session.id)) { - throw logger.DTK0053({ id: session.id }).throw() + throw diagnostics.DTK0053.throw({ id: session.id }) } this.sessions.set(session.id, session) this.bindStream(session) @@ -67,7 +67,7 @@ export class DevToolsTerminalHost implements DevToolsTerminalHostType { update(patch: PartialWithoutId): void { if (!this.sessions.has(patch.id)) { - throw logger.DTK0054({ id: patch.id }).throw() + throw diagnostics.DTK0054.throw({ id: patch.id }) } const session = this.sessions.get(patch.id)! Object.assign(session, patch) @@ -136,7 +136,7 @@ export class DevToolsTerminalHost implements DevToolsTerminalHostType { terminal: Omit, ): Promise { if (this.sessions.has(terminal.id)) { - throw logger.DTK0053({ id: terminal.id }).throw() + throw diagnostics.DTK0053.throw({ id: terminal.id }) } const { exec } = await import('tinyexec') diff --git a/packages/rolldown/package.json b/packages/rolldown/package.json index 83ff641d..5641a693 100644 --- a/packages/rolldown/package.json +++ b/packages/rolldown/package.json @@ -45,9 +45,9 @@ "diff": "catalog:deps", "get-port-please": "catalog:deps", "h3": "catalog:deps", - "logs-sdk": "catalog:deps", "mlly": "catalog:deps", "mrmime": "catalog:deps", + "nostics": "catalog:deps", "p-limit": "catalog:deps", "pathe": "catalog:deps", "publint": "catalog:deps", diff --git a/packages/rolldown/src/node/diagnostics.ts b/packages/rolldown/src/node/diagnostics.ts index d2d80982..4838c0ce 100644 --- a/packages/rolldown/src/node/diagnostics.ts +++ b/packages/rolldown/src/node/diagnostics.ts @@ -1,23 +1,14 @@ -import { colors as c } from 'devframe/utils/colors' -import { consoleReporter, createLogger, defineDiagnostics } from 'logs-sdk' -import { ansiFormatter } from 'logs-sdk/formatters/ansi' +import { defineDiagnostics, reporterLog } from 'nostics' export const diagnostics = defineDiagnostics({ docsBase: 'https://devtools.vite.dev/errors', + reporters: [reporterLog], codes: { RDDT0001: { - message: 'Rolldown logs directory `.rolldown` not found, you might want to run build with `build.rolldownOptions.devtools` enabled first.', - level: 'warn', + why: 'Rolldown logs directory `.rolldown` not found, you might want to run build with `build.rolldownOptions.devtools` enabled first.', }, RDDT0002: { - message: (p: { line: number, error: string, preview: string }) => `Rolldown log reader skipped bad line ${p.line}: ${p.error}\n${p.preview}`, - level: 'warn', + why: (p: { line: number, error: string, preview: string }) => `Rolldown log reader skipped bad line ${p.line}: ${p.error}\n${p.preview}`, }, }, }) - -export const logger = createLogger({ - diagnostics: [diagnostics], - formatter: ansiFormatter(c), - reporters: consoleReporter, -}) diff --git a/packages/rolldown/src/node/rolldown/events-reader.ts b/packages/rolldown/src/node/rolldown/events-reader.ts index d0849a33..4989f45e 100644 --- a/packages/rolldown/src/node/rolldown/events-reader.ts +++ b/packages/rolldown/src/node/rolldown/events-reader.ts @@ -5,7 +5,7 @@ import { Buffer } from 'node:buffer' import { createHash } from 'node:crypto' import fs from 'node:fs' import { parseToEvent } from '@rolldown/debug' -import { logger } from '../diagnostics' +import { diagnostics } from '../diagnostics' import { getContentByteSize } from '../utils/format' import { getContentRef, RolldownEventsManager } from './events-manager' import { RolldownLogCache } from './log-cache' @@ -386,7 +386,7 @@ export class RolldownEventsReader { } catch (e) { const preview = text.length > 256 ? `${text.slice(0, 256)}...` : text - logger.RDDT0002({ line: this.lineNumber, error: (e as Error).message, preview }).log() + diagnostics.RDDT0002.report({ line: this.lineNumber, error: (e as Error).message, preview }) } } diff --git a/packages/rolldown/src/node/rpc/utils.ts b/packages/rolldown/src/node/rpc/utils.ts index b6ac358c..74d55380 100644 --- a/packages/rolldown/src/node/rpc/utils.ts +++ b/packages/rolldown/src/node/rpc/utils.ts @@ -2,7 +2,7 @@ import type { DevToolsNodeContext } from '@vitejs/devtools-kit' import { existsSync } from 'node:fs' import process from 'node:process' import { join } from 'pathe' -import { logger } from '../diagnostics' +import { diagnostics } from '../diagnostics' import { RolldownLogsManager } from '../rolldown/logs-manager' const weakMap = new WeakMap() @@ -16,7 +16,7 @@ export function getLogsManager(context: DevToolsNodeContext): RolldownLogsManage ] const dir = dirs.find(dir => existsSync(dir)) if (!dir) { - logger.RDDT0001().log() + diagnostics.RDDT0001.report() } manager = new RolldownLogsManager(dir ?? dirs[0]!) } diff --git a/patches/devframe@0.3.0.patch b/patches/devframe@0.3.0.patch new file mode 100644 index 00000000..2988a0ad --- /dev/null +++ b/patches/devframe@0.3.0.patch @@ -0,0 +1,122 @@ +diff --git a/dist/index-DTeZXHSi.d.mts b/dist/index-DTeZXHSi.d.mts +index 3efe244a31e344efe99a12c472f75e255624f9fd..4e56e2a2cc9a9ea3fcb56a23ee534f64b6fc727e 100644 +--- a/dist/index-DTeZXHSi.d.mts ++++ b/dist/index-DTeZXHSi.d.mts +@@ -497,112 +497,11 @@ declare function createStreamSink(options?: CreateStreamSinkOptions): StreamS + declare function createStreamReader(options?: CreateStreamReaderOptions): StreamReader; + //#endregion + //#region src/types/rpc-augments.d.ts +-/** +- * To be extended +- */ +-interface DevToolsRpcClientFunctions { +- /** +- * Streaming chunk pushed from server to subscribed clients. Wired by +- * `RpcStreamingHost`; do not register manually. +- * +- * @internal +- */ +- 'devframe:streaming:chunk': (channel: string, id: string, seq: number, chunk: any) => Promise; +- /** +- * Streaming terminator pushed from server to subscribed clients. Wired by +- * `RpcStreamingHost`; do not register manually. +- * +- * @internal +- */ +- 'devframe:streaming:end': (channel: string, id: string, error?: { +- name: string; +- message: string; +- }) => Promise; +- /** +- * Server→client cancel for an in-flight upload. Wired by +- * `RpcStreamingHost`; do not register manually. +- * +- * @internal +- */ +- 'devframe:streaming:upload-cancel': (channel: string, id: string) => Promise; +-} +-/** +- * To be extended +- */ +-interface DevToolsRpcServerFunctions { +- /** +- * Subscribe a client to a shared-state key. Wired by +- * `RpcSharedStateHost`; do not register manually. +- * +- * @internal +- */ +- 'devframe:rpc:server-state:subscribe': (key: string) => Promise; +- /** +- * Read the current value for a shared-state key. Wired by +- * `RpcSharedStateHost`; do not register manually. +- * +- * @internal +- */ +- 'devframe:rpc:server-state:get': (key: string) => Promise; +- /** +- * Replace a shared-state value (from the client). Wired by +- * `RpcSharedStateHost`; do not register manually. +- * +- * @internal +- */ +- 'devframe:rpc:server-state:set': (key: string, value: any, syncId: string) => Promise; +- /** +- * Apply a patch to a shared-state value (from the client). Wired by +- * `RpcSharedStateHost`; do not register manually. +- * +- * @internal +- */ +- 'devframe:rpc:server-state:patch': (key: string, patches: any[], syncId: string) => Promise; +- /** +- * Client→server streaming subscription with optional replay cursor. +- * Wired by `RpcStreamingHost`; do not register manually. +- * +- * @internal +- */ +- 'devframe:streaming:subscribe': (channel: string, id: string, opts?: { +- afterSeq?: number; +- }) => Promise; +- /** +- * Client→server streaming unsubscribe. Wired by `RpcStreamingHost`; +- * do not register manually. +- * +- * @internal +- */ +- 'devframe:streaming:unsubscribe': (channel: string, id: string) => Promise; +- /** +- * Client→server streaming cancellation request. Wired by +- * `RpcStreamingHost`; do not register manually. +- * +- * @internal +- */ +- 'devframe:streaming:cancel': (channel: string, id: string) => Promise; +- /** +- * Client→server upload chunk. Wired by `RpcStreamingHost`; do not +- * register manually. +- * +- * @internal +- */ +- 'devframe:streaming:upload-chunk': (channel: string, id: string, seq: number, chunk: any) => Promise; +- /** +- * Client→server upload terminator. Wired by `RpcStreamingHost`; do not +- * register manually. +- * +- * @internal +- */ +- 'devframe:streaming:upload-end': (channel: string, id: string, error?: { +- name: string; +- message: string; +- }) => Promise; +-} +-/** +- * To be extended +- */ +-interface DevToolsRpcSharedStates {} ++// Re-imported from the canonical chunk to keep a single declaration of the ++// three augmentable interfaces. Without this, tsdown's client/server split ++// emits duplicate `interface` declarations in two chunks, which breaks ++// `declare module` augmentations from consumers. ++import type { E as DevToolsRpcServerFunctions, T as DevToolsRpcClientFunctions, D as DevToolsRpcSharedStates } from "./devframe-sc4cb5xr.mjs"; + //#endregion + //#region src/types/rpc.d.ts + interface RpcSharedStateGetOptions { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 49a0dba5..5104f68f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -44,8 +44,8 @@ catalogs: specifier: ^4.0.0 version: 4.0.0 devframe: - specifier: 0.2.2 - version: 0.2.2 + specifier: ^0.3.0 + version: 0.3.0 diff: specifier: ^9.0.0 version: 9.0.0 @@ -58,15 +58,15 @@ catalogs: h3: specifier: 2.0.1-rc.22 version: 2.0.1-rc.22 - logs-sdk: - specifier: ^0.0.6 - version: 0.0.6 mlly: specifier: ^1.8.2 version: 1.8.2 mrmime: specifier: ^2.0.1 version: 2.0.1 + nostics: + specifier: ^0.1.0 + version: 0.1.0 obug: specifier: ^2.1.1 version: 2.1.1 @@ -375,6 +375,11 @@ overrides: twoslash: ^0.3.8 vite: ^8.0.13 +patchedDependencies: + devframe@0.3.0: + hash: 11c90360b1a79e6b23bd30a1659078b11a1a3b45998189dd44602d6f4fd72227 + path: patches/devframe@0.3.0.patch + importers: .: @@ -487,15 +492,15 @@ importers: eslint: specifier: catalog:devtools version: 10.3.0(jiti@2.6.1) - logs-sdk: - specifier: catalog:deps - version: 0.0.6 magic-string: specifier: catalog:build version: 0.30.21 nano-staged: specifier: catalog:devtools version: 1.0.2 + nostics: + specifier: catalog:deps + version: 0.1.0 nuxt: specifier: ^4.4.5 version: 4.4.5(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@parcel/watcher@2.5.6)(@types/node@25.0.3)(@vitejs/devtools@0.1.24(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(@pnpm/logger@1001.0.1)(db0@0.3.4)(idb-keyval@6.2.2)(ioredis@5.10.1)(typescript@6.0.3)(vite@8.0.13))(@vue/compiler-sfc@3.5.34)(cac@7.0.0)(db0@0.3.4)(esbuild@0.28.0)(eslint@10.3.0(jiti@2.6.1))(idb-keyval@6.2.2)(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.1)(rollup-plugin-visualizer@7.0.1(rolldown@1.0.1)(rollup@4.60.2))(rollup@4.60.2)(terser@5.44.1)(tsx@4.22.0)(typescript@6.0.3)(vite@8.0.13)(vue-tsc@3.2.9(typescript@6.0.3))(yaml@2.8.4) @@ -570,7 +575,7 @@ importers: version: 4.8.4(change-case@5.4.4)(focus-trap@8.0.0)(fuse.js@7.3.0)(idb-keyval@6.2.2)(typescript@6.0.3)(vite@8.0.13(@types/node@25.0.3)(@vitejs/devtools@packages+core)(esbuild@0.28.0)(jiti@2.6.1)(terser@5.44.1)(tsx@4.22.0)(yaml@2.8.4))(vitepress@2.0.0-alpha.17(@types/node@25.0.3)(@vitejs/devtools@packages+core)(change-case@5.4.4)(esbuild@0.28.0)(fuse.js@7.3.0)(idb-keyval@6.2.2)(jiti@2.6.1)(oxc-minify@0.128.0)(postcss@8.5.14)(terser@5.44.1)(tsx@4.22.0)(typescript@6.0.3)(yaml@2.8.4))(vue@3.5.34(typescript@6.0.3)) devframe: specifier: catalog:deps - version: 0.2.2(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(typescript@6.0.3) + version: 0.3.0(patch_hash=11c90360b1a79e6b23bd30a1659078b11a1a3b45998189dd44602d6f4fd72227)(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(typescript@6.0.3) mermaid: specifier: catalog:docs version: 11.15.0 @@ -717,16 +722,16 @@ importers: version: 7.0.0 devframe: specifier: catalog:deps - version: 0.2.2(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(typescript@6.0.3) + version: 0.3.0(patch_hash=11c90360b1a79e6b23bd30a1659078b11a1a3b45998189dd44602d6f4fd72227)(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(typescript@6.0.3) h3: specifier: catalog:deps version: 2.0.1-rc.22 - logs-sdk: - specifier: catalog:deps - version: 0.0.6 mlly: specifier: catalog:deps version: 1.8.2 + nostics: + specifier: catalog:deps + version: 0.1.0 obug: specifier: catalog:deps version: 2.1.1 @@ -793,13 +798,13 @@ importers: version: 4.0.0 devframe: specifier: catalog:deps - version: 0.2.2(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(typescript@6.0.3) - logs-sdk: - specifier: catalog:deps - version: 0.0.6 + version: 0.3.0(patch_hash=11c90360b1a79e6b23bd30a1659078b11a1a3b45998189dd44602d6f4fd72227)(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(typescript@6.0.3) mlly: specifier: catalog:deps version: 1.8.2 + nostics: + specifier: catalog:deps + version: 0.1.0 pathe: specifier: catalog:deps version: 2.0.3 @@ -848,7 +853,7 @@ importers: version: 3.2.0 devframe: specifier: catalog:deps - version: 0.2.2(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(typescript@6.0.3) + version: 0.3.0(patch_hash=11c90360b1a79e6b23bd30a1659078b11a1a3b45998189dd44602d6f4fd72227)(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(typescript@6.0.3) diff: specifier: catalog:deps version: 9.0.0 @@ -858,15 +863,15 @@ importers: h3: specifier: catalog:deps version: 2.0.1-rc.22 - logs-sdk: - specifier: catalog:deps - version: 0.0.6 mlly: specifier: catalog:deps version: 1.8.2 mrmime: specifier: catalog:deps version: 2.0.1 + nostics: + specifier: catalog:deps + version: 0.1.0 p-limit: specifier: catalog:deps version: 7.3.0 @@ -966,7 +971,7 @@ importers: version: 4.0.0 devframe: specifier: catalog:deps - version: 0.2.2(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(typescript@6.0.3) + version: 0.3.0(patch_hash=11c90360b1a79e6b23bd30a1659078b11a1a3b45998189dd44602d6f4fd72227)(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(typescript@6.0.3) pathe: specifier: catalog:deps version: 2.0.3 @@ -1027,7 +1032,7 @@ importers: version: 4.0.0 devframe: specifier: catalog:deps - version: 0.2.2(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(typescript@6.0.3) + version: 0.3.0(patch_hash=11c90360b1a79e6b23bd30a1659078b11a1a3b45998189dd44602d6f4fd72227)(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(typescript@6.0.3) envinfo: specifier: catalog:deps version: 7.21.0 @@ -2074,6 +2079,12 @@ packages: cpu: [arm] os: [android] + '@oxc-parser/binding-android-arm-eabi@0.130.0': + resolution: {integrity: sha512-h/xYU8/7ADWzVSf5I+YalLpj33LOy9CI/zgbJNIZ5eunRBG+Czqa3lZsvuPHHf3rOt6z1c5+UzoxjbAzAvhwVw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + '@oxc-parser/binding-android-arm64@0.124.0': resolution: {integrity: sha512-ULHC/gVZ+nP4pd3kNNQTYaQ/e066BW/KuY5qUsvwkVWwOUQGDg+WpfyVOmQ4xfxoue6cMlkKkJ+ntdzfDXpNlg==} engines: {node: ^20.19.0 || >=22.12.0} @@ -2098,6 +2109,12 @@ packages: cpu: [arm64] os: [android] + '@oxc-parser/binding-android-arm64@0.130.0': + resolution: {integrity: sha512-oFWFJrsGv9siFM4HjMqKNB7IuIZD/SMmZdCXl8xyx7lDplGvPKyewpOo272rSWgMXe2Wx7bWI0Yj+gkHv4qbeg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + '@oxc-parser/binding-darwin-arm64@0.124.0': resolution: {integrity: sha512-fGJ2hw7bnbUYn6UvTjp0m4WJ9zXz3cohgcwcgeo7gUZehpPNpvcVEVeIVHNmHnAuAw/ysf4YJR8DA1E+xCA4Lw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -2122,6 +2139,12 @@ packages: cpu: [arm64] os: [darwin] + '@oxc-parser/binding-darwin-arm64@0.130.0': + resolution: {integrity: sha512-sGUzupdTplK9jQg7eJZ878HfEgQjJNBc6dAYVWJ9W5aU+J8rLfRJhTVsKThiu1pNwm6Y1qKCcbC6WhNWSXR3Ig==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + '@oxc-parser/binding-darwin-x64@0.124.0': resolution: {integrity: sha512-j0+re9pgps5BH2Tk3fm59Hi3QuLP3C4KhqXi6A+wRHHHJWDFR8mc/KI9mBrfk2JRT+15doGo+zv1eN75/9DuOw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -2146,6 +2169,12 @@ packages: cpu: [x64] os: [darwin] + '@oxc-parser/binding-darwin-x64@0.130.0': + resolution: {integrity: sha512-PsB4cdCISbC00Uy8eiD8bc2AkGWjZqrSrJnkBFuG2ptrrf6mZ2F5gLFSjOAVMMgZPg8B1D7OydJwLWSfyI2Plg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + '@oxc-parser/binding-freebsd-x64@0.124.0': resolution: {integrity: sha512-0k5mS0npnrhKy72UfF51lpOZ2ESoPWn6gdFw+RdeRWcokraDW1O2kSx3laQ+yk7cCEavQdJSpWCYS/GvBbUCXQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -2170,6 +2199,12 @@ packages: cpu: [x64] os: [freebsd] + '@oxc-parser/binding-freebsd-x64@0.130.0': + resolution: {integrity: sha512-DgABp3l38hS77JbXCV4qk1+n6DPym5u8zzwuweokezm2tX194nDSJDENbDRECxVsiNbprKATLbk+Z5wlHT0OHw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + '@oxc-parser/binding-linux-arm-gnueabihf@0.124.0': resolution: {integrity: sha512-P/i4eguRWvAUfGdfhQYg1jpwYkyUV6D3gefIH7HhmRl1Ph6P4IqTIEVcyJr1i/3vr1V5OHU4wonH6/ue/Qzvrw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -2194,6 +2229,12 @@ packages: cpu: [arm] os: [linux] + '@oxc-parser/binding-linux-arm-gnueabihf@0.130.0': + resolution: {integrity: sha512-4Kn3CTEmwFrzhTSC/JuUW16qovmaMdX7jeSKbL8w0pLtLww7To1a2XJi9Z5uD8QWUkfUHhqfV+VD6dVzBnWzoA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + '@oxc-parser/binding-linux-arm-musleabihf@0.124.0': resolution: {integrity: sha512-/ameqFQH5fFP+66Atr8Ynv/2rYe4utcU7L4MoWS5JtrFLVO78g4qDLavyIlJxa6caSwYOvG/eO3c/DXqY5/6Rw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -2218,6 +2259,12 @@ packages: cpu: [arm] os: [linux] + '@oxc-parser/binding-linux-arm-musleabihf@0.130.0': + resolution: {integrity: sha512-D35KZM3F4rRu1uAFKyBlg3Gaf/ybCjyaPR1hfgvk5ex8NtcTmRgc0JgSighEyNg96TPrFhemFba68SZuxaha8w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + '@oxc-parser/binding-linux-arm64-gnu@0.124.0': resolution: {integrity: sha512-gNeyEcXTtfrRCbj2EfxWU85Fs0wIX3p44Y3twnvuMfkWlLrb9M1Z25AYNSKjJM+fdAjeeQCjw0on47zFuBYwQw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -2246,6 +2293,13 @@ packages: os: [linux] libc: [glibc] + '@oxc-parser/binding-linux-arm64-gnu@0.130.0': + resolution: {integrity: sha512-Q9o7oVlo955KHwS8l1u0bCzIx+JsZUA3XToLXC+MsMhye/9LeBQbt84nh120cl2XLy+TEzvugYDiHShg5yaX6Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + '@oxc-parser/binding-linux-arm64-musl@0.124.0': resolution: {integrity: sha512-uvG7v4Tz9S8/PVqY0SP0DLHxo4hZGe+Pv2tGVnwcsjKCCUPjplbrFVvDzXq+kOaEoUkiCY0Kt1hlZ6FDJ1LKNQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -2274,6 +2328,13 @@ packages: os: [linux] libc: [musl] + '@oxc-parser/binding-linux-arm64-musl@0.130.0': + resolution: {integrity: sha512-EiJ/gC0ljbcwVpycC8YWw6ggMbtsPX8XMOt0mPx0aqWeMsNR+L9m05Flbvd5T+GlivG+GkSWQL7tM9SRFpM/dw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + '@oxc-parser/binding-linux-ppc64-gnu@0.124.0': resolution: {integrity: sha512-t7KZaaUhfp2au0MRpoENEFqwLKYDdptEry6V7pTAVdPEcFG4P6ii8yeGU9m6p5vb+b8WEKmdpGMNXBEYy7iJdw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -2302,6 +2363,13 @@ packages: os: [linux] libc: [glibc] + '@oxc-parser/binding-linux-ppc64-gnu@0.130.0': + resolution: {integrity: sha512-b+h/lsLLurp756dMGizNs5uPaJfyEdWrTcV5t8M609jWm1DEHB1StpRXCkyvwtkJx3m+qL5BNQ0dEKan/4yGFA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + '@oxc-parser/binding-linux-riscv64-gnu@0.124.0': resolution: {integrity: sha512-eurGGaxHZiIQ+fBSageS8TAkRqZgdOiBeqNrWAqAPup9hXBTmQ0WcBjwsLElf+3jvDL9NhnX0dOgOqPfsjSjdg==} engines: {node: ^20.19.0 || >=22.12.0} @@ -2330,6 +2398,13 @@ packages: os: [linux] libc: [glibc] + '@oxc-parser/binding-linux-riscv64-gnu@0.130.0': + resolution: {integrity: sha512-O19Cil83XAyjEFfo8WhkMwY58ALqZ7ckjGL+25mjMIuF84urWBeANH0FC8B8BsSSygWU3/1aY3ADdDbp+wlBnw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [glibc] + '@oxc-parser/binding-linux-riscv64-musl@0.124.0': resolution: {integrity: sha512-d1V7/ll1i/LhqE/gZy6Wbz6evlk0egh2XKkwMI3epiojtbtUwQSLIER0Y3yDBBocPuWOjJdvmjtEmPTTLXje/w==} engines: {node: ^20.19.0 || >=22.12.0} @@ -2358,6 +2433,13 @@ packages: os: [linux] libc: [musl] + '@oxc-parser/binding-linux-riscv64-musl@0.130.0': + resolution: {integrity: sha512-BgXRVC0+83n3YzCscLQjj6nbyeBIVeZYPTI4fFMAE4WNm2+4RXhWp03IVizL7esIz36kgmT48aebk1iM+cs8sw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [musl] + '@oxc-parser/binding-linux-s390x-gnu@0.124.0': resolution: {integrity: sha512-w1+cBvriUteOpox6ATqCFVkpGL47PFdcfCPGmgUZbd78Fw44U0gQkc+kVGvAOTvGrptMYgwomD1c6OTVvkrpGg==} engines: {node: ^20.19.0 || >=22.12.0} @@ -2386,6 +2468,13 @@ packages: os: [linux] libc: [glibc] + '@oxc-parser/binding-linux-s390x-gnu@0.130.0': + resolution: {integrity: sha512-6tJz0xvnGhsokE7N1WlUSBXibpYmT9xSJFS1Ce41Km/+8gQvdlW8MLhRv8PD0L7ix8vRG0FDDepp3jdOFzdVdw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + '@oxc-parser/binding-linux-x64-gnu@0.124.0': resolution: {integrity: sha512-RRB1evQiXRtMCsQQiAh9U0H3HzguLpE0ytfStuhRgmOj7tqUCOVxkHsvM9geZjAax6NqVRj7VXx32qjjkZPsBw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -2414,6 +2503,13 @@ packages: os: [linux] libc: [glibc] + '@oxc-parser/binding-linux-x64-gnu@0.130.0': + resolution: {integrity: sha512-9aCWj83dp3heTQGmGnZGdIWgxjZrr/7VQ0TGFHH5PKByxJKF2Hcr4qvaSUHhhGEa3MSsDjTL1YDP8RAgdL5/Cg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + '@oxc-parser/binding-linux-x64-musl@0.124.0': resolution: {integrity: sha512-asVYN0qmSHlCU8H9Q47SmeJ/Z5EG4IWCC+QGxkfFboI5qh15aLlJnHmnrV61MwQRPXGnVC/sC3qKhrUyqGxUqw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -2442,6 +2538,13 @@ packages: os: [linux] libc: [musl] + '@oxc-parser/binding-linux-x64-musl@0.130.0': + resolution: {integrity: sha512-afXt87aZBqrUVli8TB/I8H1G50RDWcwirjWtXGXYqJ2ZqWEiErH7V72j3LUSDZaivmtu2OLX0KQ/mbhP81mr7A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + '@oxc-parser/binding-openharmony-arm64@0.124.0': resolution: {integrity: sha512-nhwuxm6B8pn9lzAzMUfa571L5hCXYwQo8C8cx5aGOuHWCzruR8gPJnRRXGBci+uGaIIQEZDyU/U6HDgrSp/JlQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -2466,6 +2569,12 @@ packages: cpu: [arm64] os: [openharmony] + '@oxc-parser/binding-openharmony-arm64@0.130.0': + resolution: {integrity: sha512-I0NCrZV/YZuCGWgqwNN/GO/iXlLF2z+Wgc7u+Aa9N4P51oYeIa0XT+zVBUne4csO9GqxskXgI4g8JzzWGRpfOw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + '@oxc-parser/binding-wasm32-wasi@0.124.0': resolution: {integrity: sha512-LWuq4Dl9tff7n+HjJcqoBjDlVCtruc0shgtdtGM+rTUIE9aFxHA/P+wCYR+aWMjN8m9vNaRME/sKXErmhmeKrA==} engines: {node: '>=14.0.0'} @@ -2486,6 +2595,11 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} cpu: [wasm32] + '@oxc-parser/binding-wasm32-wasi@0.130.0': + resolution: {integrity: sha512-sJgQkGaBX0WJvPUDfwciex6IcTk5O5NLQ1bhEb6f3nBruh1GshKMRSMt2bxZlYrgBzjyBbJzsnO+InPG0bg+fA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [wasm32] + '@oxc-parser/binding-win32-arm64-msvc@0.124.0': resolution: {integrity: sha512-aOh3Lf3AeH0dgzT4yBXcArFZ8VhqNXwZ/xlN0GqBtgVaGoHOOqL2YHlcVIgT+ghsXPVR2PTtYgBiQ1CNK7jp5A==} engines: {node: ^20.19.0 || >=22.12.0} @@ -2510,6 +2624,12 @@ packages: cpu: [arm64] os: [win32] + '@oxc-parser/binding-win32-arm64-msvc@0.130.0': + resolution: {integrity: sha512-bjcma99sQrNh6RY4mPO9yTkfxql6TDFoN3HWdK31RCKXwNhcDgJXW/l8PUtzKNiQ+9vpKJfJtQq+LklBuxSOBA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + '@oxc-parser/binding-win32-ia32-msvc@0.124.0': resolution: {integrity: sha512-sib5xC0nz/+SCpaETBuHBz4SXS02KuG5HtyOcHsO/SK5ZvLRGhOZx0elDKawjb6adFkD7dQCqpXUS25wY6ELKQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -2534,6 +2654,12 @@ packages: cpu: [ia32] os: [win32] + '@oxc-parser/binding-win32-ia32-msvc@0.130.0': + resolution: {integrity: sha512-hRYbv6HhpSTzT4xTiIkadLI7upLQxuOdLPR/9nL1fTjwhgutBTPXrwaAPb/jTFVx6/8C7Jb5HcUKhmNwloTbFA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] + '@oxc-parser/binding-win32-x64-msvc@0.124.0': resolution: {integrity: sha512-UgojtjGUgZgAZQYt7SC6VO65OVdxEkRe2q+2vbHJO//18qw3Hrk6UvHGQKldsQKgbVcIBT/YBrt85YberiYIPQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -2558,6 +2684,12 @@ packages: cpu: [x64] os: [win32] + '@oxc-parser/binding-win32-x64-msvc@0.130.0': + resolution: {integrity: sha512-RBpA9TsRucJq6HNVNCFF1iKg+QeTkLdZf7hi4xaOGCPvMZWvDHjQgSOEZMUpuW4JNciHbxNhLEYmz5CVygjVGQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + '@oxc-project/types@0.124.0': resolution: {integrity: sha512-VBFWMTBvHxS11Z5Lvlr3IWgrwhMTXV+Md+EQF0Xf60+wAdsGFTBx7X7K/hP4pi8N7dcm1RvcHwDxZ16Qx8keUg==} @@ -3964,11 +4096,6 @@ packages: peerDependencies: vue: ^3.3.0 - '@vitejs/devtools-kit@0.1.23': - resolution: {integrity: sha512-WsMvJ9GISv/gm/DIJvpqVz4nQuj89MFEbMf0iTb7MmTGb2mXEzG9tcWBpG36bjoziqxUuRBoi9O7PkQoCaTQpQ==} - peerDependencies: - vite: ^8.0.13 - '@vitejs/devtools-kit@0.1.24': resolution: {integrity: sha512-sHM4i80Rrx4HTv/c2d28pQpeMz99GQe/2lVvJvna9t/YcoVouqpsms8oKiF/NcX8474A5gx3TtJHXWvqbov1dg==} peerDependencies: @@ -5129,8 +5256,8 @@ packages: '@modelcontextprotocol/sdk': optional: true - devframe@0.2.3: - resolution: {integrity: sha512-wQjB78wPADHtm7Gt6Atd5qHAsRpXGjJKhrebz2SncnybK6k+M9Lccu8ERtD+1+3a6Bp2JevNywei5BCHqYoHLw==} + devframe@0.3.0: + resolution: {integrity: sha512-Yli2NJ2Xs5pK69YhdkrPHU7MccVsCuNj15o5l5lrOjDna3g5c6A/7br03w0jVzl2Rl0VJTZ9YMN7GaomDAFrRQ==} peerDependencies: '@modelcontextprotocol/sdk': ^1.0.0 peerDependenciesMeta: @@ -6827,6 +6954,9 @@ packages: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} + nostics@0.1.0: + resolution: {integrity: sha512-gSujQXUjmUOFVum7XazE2EcoHYZB3Et0dZwiQh1plulZdolEZL+Y7TOu9yVsXCxxUqfw5q0+svxJJXvynygKEQ==} + npm-run-path@4.0.1: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} @@ -6944,6 +7074,10 @@ packages: resolution: {integrity: sha512-S6eFI+VLkpyA+/Lf8z6qURjDV6Mgo74SLNznNopHTlQW3hedv2MB/z31kBRuBCCTqZN9HHdva0ojljEhPnBKFA==} engines: {node: ^20.19.0 || >=22.12.0} + oxc-parser@0.130.0: + resolution: {integrity: sha512-X0PJ+NmOok8qP3vK9uaW431ngkdM9UPEK7KG466urtIL2+EYTEgbZK2yqe2MWKJKBjRlFweP/pJPx0x9muMEVw==} + engines: {node: ^20.19.0 || >=22.12.0} + oxc-transform@0.128.0: resolution: {integrity: sha512-8DfEHlmUiLOHlCK9DGX+d5tORc1xwPPvoRSHSJCYgLHyGjKp4PvfBrvgi59DkEW0SMOWfO8GL9t+R7vdKtupbg==} engines: {node: ^20.19.0 || >=22.12.0} @@ -10329,6 +10463,9 @@ snapshots: '@oxc-parser/binding-android-arm-eabi@0.129.0': optional: true + '@oxc-parser/binding-android-arm-eabi@0.130.0': + optional: true + '@oxc-parser/binding-android-arm64@0.124.0': optional: true @@ -10341,6 +10478,9 @@ snapshots: '@oxc-parser/binding-android-arm64@0.129.0': optional: true + '@oxc-parser/binding-android-arm64@0.130.0': + optional: true + '@oxc-parser/binding-darwin-arm64@0.124.0': optional: true @@ -10353,6 +10493,9 @@ snapshots: '@oxc-parser/binding-darwin-arm64@0.129.0': optional: true + '@oxc-parser/binding-darwin-arm64@0.130.0': + optional: true + '@oxc-parser/binding-darwin-x64@0.124.0': optional: true @@ -10365,6 +10508,9 @@ snapshots: '@oxc-parser/binding-darwin-x64@0.129.0': optional: true + '@oxc-parser/binding-darwin-x64@0.130.0': + optional: true + '@oxc-parser/binding-freebsd-x64@0.124.0': optional: true @@ -10377,6 +10523,9 @@ snapshots: '@oxc-parser/binding-freebsd-x64@0.129.0': optional: true + '@oxc-parser/binding-freebsd-x64@0.130.0': + optional: true + '@oxc-parser/binding-linux-arm-gnueabihf@0.124.0': optional: true @@ -10389,6 +10538,9 @@ snapshots: '@oxc-parser/binding-linux-arm-gnueabihf@0.129.0': optional: true + '@oxc-parser/binding-linux-arm-gnueabihf@0.130.0': + optional: true + '@oxc-parser/binding-linux-arm-musleabihf@0.124.0': optional: true @@ -10401,6 +10553,9 @@ snapshots: '@oxc-parser/binding-linux-arm-musleabihf@0.129.0': optional: true + '@oxc-parser/binding-linux-arm-musleabihf@0.130.0': + optional: true + '@oxc-parser/binding-linux-arm64-gnu@0.124.0': optional: true @@ -10413,6 +10568,9 @@ snapshots: '@oxc-parser/binding-linux-arm64-gnu@0.129.0': optional: true + '@oxc-parser/binding-linux-arm64-gnu@0.130.0': + optional: true + '@oxc-parser/binding-linux-arm64-musl@0.124.0': optional: true @@ -10425,6 +10583,9 @@ snapshots: '@oxc-parser/binding-linux-arm64-musl@0.129.0': optional: true + '@oxc-parser/binding-linux-arm64-musl@0.130.0': + optional: true + '@oxc-parser/binding-linux-ppc64-gnu@0.124.0': optional: true @@ -10437,6 +10598,9 @@ snapshots: '@oxc-parser/binding-linux-ppc64-gnu@0.129.0': optional: true + '@oxc-parser/binding-linux-ppc64-gnu@0.130.0': + optional: true + '@oxc-parser/binding-linux-riscv64-gnu@0.124.0': optional: true @@ -10449,6 +10613,9 @@ snapshots: '@oxc-parser/binding-linux-riscv64-gnu@0.129.0': optional: true + '@oxc-parser/binding-linux-riscv64-gnu@0.130.0': + optional: true + '@oxc-parser/binding-linux-riscv64-musl@0.124.0': optional: true @@ -10461,6 +10628,9 @@ snapshots: '@oxc-parser/binding-linux-riscv64-musl@0.129.0': optional: true + '@oxc-parser/binding-linux-riscv64-musl@0.130.0': + optional: true + '@oxc-parser/binding-linux-s390x-gnu@0.124.0': optional: true @@ -10473,6 +10643,9 @@ snapshots: '@oxc-parser/binding-linux-s390x-gnu@0.129.0': optional: true + '@oxc-parser/binding-linux-s390x-gnu@0.130.0': + optional: true + '@oxc-parser/binding-linux-x64-gnu@0.124.0': optional: true @@ -10485,6 +10658,9 @@ snapshots: '@oxc-parser/binding-linux-x64-gnu@0.129.0': optional: true + '@oxc-parser/binding-linux-x64-gnu@0.130.0': + optional: true + '@oxc-parser/binding-linux-x64-musl@0.124.0': optional: true @@ -10497,6 +10673,9 @@ snapshots: '@oxc-parser/binding-linux-x64-musl@0.129.0': optional: true + '@oxc-parser/binding-linux-x64-musl@0.130.0': + optional: true + '@oxc-parser/binding-openharmony-arm64@0.124.0': optional: true @@ -10509,6 +10688,9 @@ snapshots: '@oxc-parser/binding-openharmony-arm64@0.129.0': optional: true + '@oxc-parser/binding-openharmony-arm64@0.130.0': + optional: true + '@oxc-parser/binding-wasm32-wasi@0.124.0(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': dependencies: '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) @@ -10538,6 +10720,13 @@ snapshots: '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) optional: true + '@oxc-parser/binding-wasm32-wasi@0.130.0': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + optional: true + '@oxc-parser/binding-win32-arm64-msvc@0.124.0': optional: true @@ -10550,6 +10739,9 @@ snapshots: '@oxc-parser/binding-win32-arm64-msvc@0.129.0': optional: true + '@oxc-parser/binding-win32-arm64-msvc@0.130.0': + optional: true + '@oxc-parser/binding-win32-ia32-msvc@0.124.0': optional: true @@ -10562,6 +10754,9 @@ snapshots: '@oxc-parser/binding-win32-ia32-msvc@0.129.0': optional: true + '@oxc-parser/binding-win32-ia32-msvc@0.130.0': + optional: true + '@oxc-parser/binding-win32-x64-msvc@0.124.0': optional: true @@ -10574,6 +10769,9 @@ snapshots: '@oxc-parser/binding-win32-x64-msvc@0.129.0': optional: true + '@oxc-parser/binding-win32-x64-msvc@0.130.0': + optional: true + '@oxc-project/types@0.124.0': {} '@oxc-project/types@0.126.0': {} @@ -11990,23 +12188,6 @@ snapshots: '@visual-json/core': 0.4.0 vue: 3.5.34(typescript@6.0.3) - '@vitejs/devtools-kit@0.1.23(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(typescript@6.0.3)(vite@8.0.13)': - dependencies: - birpc: 4.0.0 - devframe: 0.2.3(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(typescript@6.0.3) - logs-sdk: 0.0.6 - mlly: 1.8.2 - pathe: 2.0.3 - perfect-debounce: 2.1.0 - tinyexec: 1.1.2 - vite: 8.0.13(@types/node@25.0.3)(@vitejs/devtools@0.1.24(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(@pnpm/logger@1001.0.1)(db0@0.3.4)(idb-keyval@6.2.2)(ioredis@5.10.1)(typescript@6.0.3)(vite@8.0.13))(esbuild@0.28.0)(jiti@2.6.1)(terser@5.44.1)(tsx@4.22.0)(yaml@2.8.4) - transitivePeerDependencies: - - '@modelcontextprotocol/sdk' - - bufferutil - - crossws - - typescript - - utf-8-validate - '@vitejs/devtools-kit@0.1.24(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(typescript@6.0.3)(vite@8.0.13)': dependencies: birpc: 4.0.0 @@ -12023,7 +12204,6 @@ snapshots: - crossws - typescript - utf-8-validate - optional: true '@vitejs/devtools-rolldown@0.1.24(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(@pnpm/logger@1001.0.1)(db0@0.3.4)(idb-keyval@6.2.2)(ioredis@5.10.1)(typescript@6.0.3)(vite@8.0.13)(vue@3.5.34(typescript@6.0.3))': dependencies: @@ -13420,14 +13600,14 @@ snapshots: - typescript - utf-8-validate - devframe@0.2.3(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(typescript@6.0.3): + devframe@0.3.0(patch_hash=11c90360b1a79e6b23bd30a1659078b11a1a3b45998189dd44602d6f4fd72227)(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(typescript@6.0.3): dependencies: '@valibot/to-json-schema': 1.7.0(valibot@1.4.0(typescript@6.0.3)) birpc: 4.0.0 cac: 7.0.0 h3: 2.0.1-rc.22 - logs-sdk: 0.0.6 mrmime: 2.0.1 + nostics: 0.1.0 pathe: 2.0.3 valibot: 1.4.0(typescript@6.0.3) ws: 8.20.1 @@ -15406,6 +15586,12 @@ snapshots: normalize-path@3.0.0: {} + nostics@0.1.0: + dependencies: + magic-string: 0.30.21 + oxc-parser: 0.130.0 + unplugin: 3.0.0 + npm-run-path@4.0.1: dependencies: path-key: 3.1.1 @@ -16013,6 +16199,31 @@ snapshots: '@oxc-parser/binding-win32-ia32-msvc': 0.129.0 '@oxc-parser/binding-win32-x64-msvc': 0.129.0 + oxc-parser@0.130.0: + dependencies: + '@oxc-project/types': 0.130.0 + optionalDependencies: + '@oxc-parser/binding-android-arm-eabi': 0.130.0 + '@oxc-parser/binding-android-arm64': 0.130.0 + '@oxc-parser/binding-darwin-arm64': 0.130.0 + '@oxc-parser/binding-darwin-x64': 0.130.0 + '@oxc-parser/binding-freebsd-x64': 0.130.0 + '@oxc-parser/binding-linux-arm-gnueabihf': 0.130.0 + '@oxc-parser/binding-linux-arm-musleabihf': 0.130.0 + '@oxc-parser/binding-linux-arm64-gnu': 0.130.0 + '@oxc-parser/binding-linux-arm64-musl': 0.130.0 + '@oxc-parser/binding-linux-ppc64-gnu': 0.130.0 + '@oxc-parser/binding-linux-riscv64-gnu': 0.130.0 + '@oxc-parser/binding-linux-riscv64-musl': 0.130.0 + '@oxc-parser/binding-linux-s390x-gnu': 0.130.0 + '@oxc-parser/binding-linux-x64-gnu': 0.130.0 + '@oxc-parser/binding-linux-x64-musl': 0.130.0 + '@oxc-parser/binding-openharmony-arm64': 0.130.0 + '@oxc-parser/binding-wasm32-wasi': 0.130.0 + '@oxc-parser/binding-win32-arm64-msvc': 0.130.0 + '@oxc-parser/binding-win32-ia32-msvc': 0.130.0 + '@oxc-parser/binding-win32-x64-msvc': 0.130.0 + oxc-transform@0.128.0: optionalDependencies: '@oxc-transform/binding-android-arm-eabi': 0.128.0 @@ -17699,7 +17910,7 @@ snapshots: vite-plugin-inspect@12.0.0-beta.1(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(@nuxt/kit@4.4.5(magicast@0.5.2))(typescript@6.0.3)(vite@8.0.13): dependencies: - '@vitejs/devtools-kit': 0.1.23(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(typescript@6.0.3)(vite@8.0.13) + '@vitejs/devtools-kit': 0.1.24(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(typescript@6.0.3)(vite@8.0.13) ansis: 4.2.0 error-stack-parser-es: 1.0.5 obug: 2.1.1 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 7c2aeb59..341856c3 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -4,7 +4,6 @@ allowBuilds: simple-git-hooks: true unrs-resolver: true vue-demi: true - ignoreWorkspaceRootCheck: true shamefullyHoist: true shellEmulator: true @@ -33,6 +32,8 @@ overrides: semver: 'catalog:resolutions' twoslash: 'catalog:docs' vite: 'catalog:build' +patchedDependencies: + devframe@0.3.0: patches/devframe@0.3.0.patch catalogs: build: '@antfu/ni': ^30.1.0 @@ -57,15 +58,14 @@ catalogs: '@rolldown/debug': ^1.0.1 birpc: ^4.0.0 cac: ^7.0.0 - # 0.2.3 emits dts in a way that breaks kit/core's `declare module` augmentations. - devframe: 0.2.2 + devframe: ^0.3.0 diff: ^9.0.0 envinfo: ^7.21.0 get-port-please: ^3.2.0 h3: 2.0.1-rc.22 - logs-sdk: ^0.0.6 mlly: ^1.8.2 mrmime: ^2.0.1 + nostics: ^0.1.0 obug: ^2.1.1 p-limit: ^7.3.0 pathe: ^2.0.3 diff --git a/skills/vite-devtools-kit/SKILL.md b/skills/vite-devtools-kit/SKILL.md index 26a5e554..6c25ae5f 100644 --- a/skills/vite-devtools-kit/SKILL.md +++ b/skills/vite-devtools-kit/SKILL.md @@ -31,7 +31,7 @@ A DevTools plugin extends a Vite plugin with a `devtools.setup(ctx)` hook. The c | `ctx.rpc.sharedState` | devframe | Synchronized server-client state | | `ctx.rpc.streaming` | devframe | Streaming channels — chunk-style server↔client data with cancellation, replay, Web Streams interop | | `ctx.views` | devframe | Host static files for UI (`hostStatic(base, distDir)`) | -| `ctx.diagnostics` | devframe | Structured diagnostics host (logs-sdk) — register custom error codes | +| `ctx.diagnostics` | devframe | Structured diagnostics host (nostics) — register custom error codes | | `ctx.createJsonRenderer` | **kit** | Create server-side JSON render specs for zero-client-code UIs | | `ctx.viteConfig` | core | Resolved Vite configuration | | `ctx.viteServer` | core | Dev server instance (dev mode only) | @@ -666,7 +666,7 @@ Real-world example plugins in the repo — reference their code structure and pa - [JSON Render Patterns](./references/json-render-patterns.md) - Server-side JSON specs, components, state binding - [Terminals Patterns](./references/terminals-patterns.md) - Child processes, custom streams, session lifecycle - [Messages Patterns](./references/messages-patterns.md) - Message entries, toast notifications, and handle patterns -- [Diagnostics Patterns](./references/diagnostics-patterns.md) - Coded errors / warnings via `ctx.diagnostics` (logs-sdk integration) +- [Diagnostics Patterns](./references/diagnostics-patterns.md) - Coded errors / warnings via `ctx.diagnostics` (nostics integration) - [Commands Patterns](./references/commands-patterns.md) - Command registration, sub-commands, keybindings, palette integration - [When Clauses](./references/when-clauses.md) - Conditional expression syntax, context variables, API reference - [Remote Client Patterns](./references/remote-client-patterns.md) - Remote-hosted iframe docks, `connectRemoteDevTools`, trust model diff --git a/skills/vite-devtools-kit/references/diagnostics-patterns.md b/skills/vite-devtools-kit/references/diagnostics-patterns.md index e68facca..bb76ec43 100644 --- a/skills/vite-devtools-kit/references/diagnostics-patterns.md +++ b/skills/vite-devtools-kit/references/diagnostics-patterns.md @@ -1,22 +1,22 @@ # Structured Diagnostics Patterns -`ctx.diagnostics` exposes a shared [`logs-sdk`](https://github.com/vercel-labs/logs-sdk) logger and lets plugins register their own coded errors / warnings without depending on `logs-sdk` directly. Use it for *author-defined coded conditions* with a stable code and a docs URL — distinct from `ctx.messages`, which is for free-form user-facing notifications shown in the DevTools UI. +`ctx.diagnostics` exposes a shared [`nostics`](https://github.com/vercel-labs/nostics) registry and lets plugins register their own coded errors / warnings without depending on `nostics` directly. Use it for *author-defined coded conditions* with a stable code and a docs URL — distinct from `ctx.messages`, which is for free-form user-facing notifications shown in the DevTools UI. ## API Surface ```ts interface DevToolsDiagnosticsHost { - /** Combined logs-sdk Logger across all registered diagnostics. Always returns the freshest logger — rebuilt on each `register()`. */ - readonly logger: Logger + /** Proxy-backed lookup of every registered code by name. Each entry is a + * `nostics` handle with `.report()` and `.throw()` methods. Loosely typed + * because it spans heterogeneous definitions from different integrations. */ + readonly logger: Record /** Register additional diagnostic definitions with the host. */ - register: (definitions: DiagnosticsResult) => void + register: (definitions: Record) => void - /** Re-export of logs-sdk's `defineDiagnostics`. */ + /** Mirror of `nostics`'s `defineDiagnostics`, pre-wired with the host's + * ANSI console reporter. Plugins typically omit `reporters`. */ defineDiagnostics: typeof defineDiagnostics - - /** Re-export of logs-sdk's `createLogger`. */ - createLogger: typeof createLogger } ``` @@ -41,11 +41,10 @@ ctx.diagnostics.defineDiagnostics({ docsBase: 'https://example.com/errors', codes: { MYP0001: { - message: 'Static string message', + why: 'Static string message', // OR a template function: - // message: (p: { name: string }) => `Plugin "${p.name}" failed`, - hint: 'Optional secondary guidance — shown after the message.', - level: 'warn', // 'error' (default) | 'warn' | 'suggestion' | 'deprecation' + // why: (p: { name: string }) => `Plugin "${p.name}" failed`, + fix: 'Optional secondary remediation guidance — shown after the message.', }, }, }) @@ -65,12 +64,11 @@ export function MyPlugin(): PluginWithDevTools { docsBase: 'https://my-plugin.dev/errors', codes: { MYP0001: { - message: (p: { name: string }) => `Plugin "${p.name}" is not configured`, - hint: 'Pass an options object to the plugin in `vite.config.ts`.', + why: (p: { name: string }) => `Plugin "${p.name}" is not configured`, + fix: 'Pass an options object to the plugin in `vite.config.ts`.', }, MYP0002: { - message: 'Cache directory missing — running cold.', - level: 'warn', + why: 'Cache directory missing — running cold.', }, }, }) @@ -83,56 +81,43 @@ export function MyPlugin(): PluginWithDevTools { ## Emit a Diagnostic -Each code becomes a callable factory on `ctx.diagnostics.logger`. Each call returns an object with `.throw()`, `.warn()`, `.error()`, `.log()`, and `.format()`. +Each registered code is reachable as a property on `ctx.diagnostics.logger`. Every handle exposes `.throw(params)` and `.report(params)`. ```ts // Throw — control flow stops here. Prefix with `throw` for TS narrowing. -throw ctx.diagnostics.logger.MYP0001({ name: 'foo' }).throw() - -// Log without throwing -ctx.diagnostics.logger.MYP0002().log() +throw ctx.diagnostics.logger.MYP0001.throw({ name: 'foo' }) -// Override level per call -ctx.diagnostics.logger.MYP0002().warn() +// Report without throwing (goes through the host's reporter) +ctx.diagnostics.logger.MYP0002.report() -// Attach a cause -ctx.diagnostics.logger.MYP0001({ name }, { cause: error }).log() +// Attach a cause via the params object +ctx.diagnostics.logger.MYP0001.report({ name, cause: error }) ``` -## Loosely Typed `logger` vs Typed Reference +## Loosely Typed `logger` vs Typed Handle -`ctx.diagnostics.logger` covers an unbounded set of registered codes, so TypeScript can't narrow them. For full autocompletion, keep your own typed reference via `createLogger`: +`ctx.diagnostics.logger` is a proxy covering an unbounded set of registered codes, so TypeScript can't narrow them. For full autocompletion, keep your own reference to the typed handle returned from `defineDiagnostics()`: ```ts const diagnostics = ctx.diagnostics.defineDiagnostics({ /* ... */ }) -// Register so the shared logger sees it too +// Register so the shared lookup sees it too ctx.diagnostics.register(diagnostics) -// Typed reference — autocompletes MYP* codes -const logger = ctx.diagnostics.createLogger({ diagnostics: [diagnostics] }) -logger.MYP0001({ name: 'foo' }).warn() +// Typed handle — autocompletes MYP* codes +diagnostics.MYP0001.report({ name: 'foo' }) ``` -Both loggers share the host's default formatter (ANSI) and reporter (console). +Both paths share the host's default formatter (ANSI) and reporter (console). ## Anti-Patterns ```ts -// ❌ Caching the getter — stale after a later register() call -const log = ctx.diagnostics.logger -log.MYP0001({ name: 'foo' }).log() - -// ✅ Always go through the getter -ctx.diagnostics.logger.MYP0001({ name: 'foo' }).log() -``` - -```ts -// ❌ Using a raw throw with an ad-hoc string +// ❌ Raw throw with an ad-hoc string throw new Error('Plugin foo not configured') // ✅ Use a structured code -throw ctx.diagnostics.logger.MYP0001({ name: 'foo' }).throw() +throw ctx.diagnostics.logger.MYP0001.throw({ name: 'foo' }) ``` ```ts @@ -140,7 +125,7 @@ throw ctx.diagnostics.logger.MYP0001({ name: 'foo' }).throw() ctx.messages.add({ message: 'Plugin failed: bad config', level: 'error' }) // ✅ Use ctx.diagnostics for coded conditions; ctx.messages for UI activity -ctx.diagnostics.logger.MYP0001({ name }).log() +ctx.diagnostics.logger.MYP0001.report({ name }) ``` ## Document Your Codes @@ -166,4 +151,4 @@ Each page covers: message, cause, example trigger, and fix. The `docsBase` you s - `packages/core/src/node/diagnostics.ts` — `DTK*` codes (Vite-specific) - `packages/rolldown/src/node/diagnostics.ts` — `RDDT*` codes (rolldown UI) -Each defines a `diagnostics` object via `defineDiagnostics(...)` and either keeps its own `createLogger`-built `logger` or — in plugin setup — calls `ctx.diagnostics.register(diagnostics)` to fold the codes into the shared host logger. +Each defines a `diagnostics` object via `defineDiagnostics(...)` and either uses its own typed handle directly, or — in plugin setup — calls `ctx.diagnostics.register(diagnostics)` to fold the codes into the shared host lookup.