@vitejs/devtools-kit 0.1.8 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.d.ts +2 -2
- package/dist/constants.d.ts +1 -1
- package/dist/{index-BSLgRVfr.d.ts → index-BMTnY3zc.d.ts} +182 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +5 -4
- package/dist/utils/shared-state.d.ts +1 -1
- package/dist/utils/when.d.ts +2 -0
- package/dist/utils/when.js +66 -0
- package/dist/when-snfIizvo.d.ts +47 -0
- package/package.json +4 -3
- package/skills/vite-devtools-kit/SKILL.md +28 -1
- package/skills/vite-devtools-kit/references/commands-patterns.md +241 -0
- package/skills/vite-devtools-kit/references/dock-entry-types.md +1 -1
- package/skills/vite-devtools-kit/references/when-clauses.md +160 -0
- /package/dist/{shared-state-NxkOZ3u0.d.ts → shared-state-CQAciU8Y.d.ts} +0 -0
package/dist/client.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { _ as
|
|
2
|
-
export { CLIENT_CONTEXT_KEY, DevToolsClientContext, DevToolsClientRpcHost, DevToolsRpcClient, DevToolsRpcClientCall, DevToolsRpcClientCallEvent, DevToolsRpcClientCallOptional, DevToolsRpcClientMode, DevToolsRpcClientOptions, DockClientScriptContext, DockClientType, DockEntryState, DockEntryStateEvents, DockPanelStorage, DocksContext, DocksEntriesContext, DocksPanelContext, RpcClientEvents, getDevToolsClientContext, getDevToolsRpcClient };
|
|
1
|
+
import { S as getDevToolsRpcClient, _ as DevToolsRpcClientCall, a as DevToolsClientContext, b as DevToolsRpcClientMode, c as DockEntryState, d as DocksContext, f as DocksEntriesContext, g as DevToolsRpcClient, h as WhenClauseContext, i as CommandsContext, l as DockEntryStateEvents, m as RpcClientEvents, n as getDevToolsClientContext, o as DevToolsClientRpcHost, p as DocksPanelContext, r as DockClientScriptContext, s as DockClientType, t as CLIENT_CONTEXT_KEY, u as DockPanelStorage, v as DevToolsRpcClientCallEvent, x as DevToolsRpcClientOptions, y as DevToolsRpcClientCallOptional } from "./index-BMTnY3zc.js";
|
|
2
|
+
export { CLIENT_CONTEXT_KEY, CommandsContext, DevToolsClientContext, DevToolsClientRpcHost, DevToolsRpcClient, DevToolsRpcClientCall, DevToolsRpcClientCallEvent, DevToolsRpcClientCallOptional, DevToolsRpcClientMode, DevToolsRpcClientOptions, DockClientScriptContext, DockClientType, DockEntryState, DockEntryStateEvents, DockPanelStorage, DocksContext, DocksEntriesContext, DocksPanelContext, RpcClientEvents, WhenClauseContext, getDevToolsClientContext, getDevToolsRpcClient };
|
package/dist/constants.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { t as EventEmitter } from "./events-BTCXlxeC.js";
|
|
2
|
-
import {
|
|
2
|
+
import { t as WhenContext } from "./when-snfIizvo.js";
|
|
3
|
+
import { o as SharedState } from "./shared-state-CQAciU8Y.js";
|
|
3
4
|
import { RpcDefinitionsFilter, RpcDefinitionsToFunctions, RpcFunctionsCollector, RpcFunctionsCollectorBase } from "@vitejs/devtools-rpc";
|
|
4
5
|
import { WebSocketRpcClientOptions } from "@vitejs/devtools-rpc/presets/ws/client";
|
|
5
6
|
import { DevToolsNodeRpcSessionMeta } from "@vitejs/devtools-rpc/presets/ws/server";
|
|
@@ -150,6 +151,127 @@ interface DevToolsLogsHost {
|
|
|
150
151
|
clear: () => Promise<void>;
|
|
151
152
|
}
|
|
152
153
|
//#endregion
|
|
154
|
+
//#region src/types/commands.d.ts
|
|
155
|
+
interface DevToolsCommandKeybinding {
|
|
156
|
+
/**
|
|
157
|
+
* Keyboard shortcut string.
|
|
158
|
+
* Use "Mod" for platform-aware modifier (Cmd on macOS, Ctrl elsewhere).
|
|
159
|
+
* Examples: "Mod+K", "Mod+Shift+P", "Alt+N"
|
|
160
|
+
*/
|
|
161
|
+
key: string;
|
|
162
|
+
}
|
|
163
|
+
interface DevToolsCommandBase {
|
|
164
|
+
/**
|
|
165
|
+
* Unique namespaced ID, e.g. "vite:open-in-editor"
|
|
166
|
+
*/
|
|
167
|
+
id: string;
|
|
168
|
+
title: string;
|
|
169
|
+
description?: string;
|
|
170
|
+
/**
|
|
171
|
+
* Iconify icon string, e.g. "ph:pencil-duotone"
|
|
172
|
+
*/
|
|
173
|
+
icon?: string;
|
|
174
|
+
category?: string;
|
|
175
|
+
/**
|
|
176
|
+
* Whether to show in command palette. Default: true
|
|
177
|
+
*
|
|
178
|
+
* - `true` — show the command and flatten its children into search results
|
|
179
|
+
* - `false` — hide the command entirely from the palette
|
|
180
|
+
* - `'without-children'` — show the command but don't flatten children into top-level search (children are still accessible via drill-down)
|
|
181
|
+
*/
|
|
182
|
+
showInPalette?: boolean | 'without-children';
|
|
183
|
+
/**
|
|
184
|
+
* Optional context expression for conditional visibility.
|
|
185
|
+
* When set, the command is only shown in the palette and only executable
|
|
186
|
+
* when the expression evaluates to true.
|
|
187
|
+
*
|
|
188
|
+
* Uses the same syntax as keybinding `when` clauses.
|
|
189
|
+
* @example 'clientType == embedded'
|
|
190
|
+
* @example 'dockOpen && !paletteOpen'
|
|
191
|
+
*/
|
|
192
|
+
when?: string;
|
|
193
|
+
/**
|
|
194
|
+
* Default keyboard shortcut(s) for this command
|
|
195
|
+
*/
|
|
196
|
+
keybindings?: DevToolsCommandKeybinding[];
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Server command input — what plugins pass to `ctx.commands.register()`.
|
|
200
|
+
*/
|
|
201
|
+
interface DevToolsServerCommandInput extends DevToolsCommandBase {
|
|
202
|
+
/**
|
|
203
|
+
* Handler for this command. Optional if the command only serves as a group for children.
|
|
204
|
+
*/
|
|
205
|
+
handler?: (...args: any[]) => any | Promise<any>;
|
|
206
|
+
/**
|
|
207
|
+
* Static sub-commands. Two levels max (parent → children).
|
|
208
|
+
* Each child must have a globally unique `id`.
|
|
209
|
+
*/
|
|
210
|
+
children?: DevToolsServerCommandInput[];
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Serializable server command entry — sent over RPC (no handler).
|
|
214
|
+
*/
|
|
215
|
+
interface DevToolsServerCommandEntry extends DevToolsCommandBase {
|
|
216
|
+
source: 'server';
|
|
217
|
+
children?: DevToolsServerCommandEntry[];
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Client command — registered in the webcomponent context.
|
|
221
|
+
*/
|
|
222
|
+
interface DevToolsClientCommand extends DevToolsCommandBase {
|
|
223
|
+
source: 'client';
|
|
224
|
+
/**
|
|
225
|
+
* Action for this command. Optional if the command only serves as a group for children.
|
|
226
|
+
* Return sub-commands for dynamic nested palette menus (runtime submenus).
|
|
227
|
+
*/
|
|
228
|
+
action?: (...args: any[]) => void | DevToolsClientCommand[] | Promise<void | DevToolsClientCommand[]>;
|
|
229
|
+
/**
|
|
230
|
+
* Static sub-commands. Two levels max (parent → children).
|
|
231
|
+
*/
|
|
232
|
+
children?: DevToolsClientCommand[];
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Union of command entries visible in the palette.
|
|
236
|
+
*/
|
|
237
|
+
type DevToolsCommandEntry = DevToolsServerCommandEntry | DevToolsClientCommand;
|
|
238
|
+
interface DevToolsCommandHandle {
|
|
239
|
+
readonly id: string;
|
|
240
|
+
update: (patch: Partial<Omit<DevToolsServerCommandInput, 'id'>>) => void;
|
|
241
|
+
unregister: () => void;
|
|
242
|
+
}
|
|
243
|
+
interface DevToolsCommandsHostEvents {
|
|
244
|
+
'command:registered': (command: DevToolsServerCommandEntry) => void;
|
|
245
|
+
'command:unregistered': (id: string) => void;
|
|
246
|
+
}
|
|
247
|
+
interface DevToolsCommandsHost {
|
|
248
|
+
readonly commands: Map<string, DevToolsServerCommandInput>;
|
|
249
|
+
readonly events: EventEmitter<DevToolsCommandsHostEvents>;
|
|
250
|
+
/**
|
|
251
|
+
* Register a command (with optional children).
|
|
252
|
+
*/
|
|
253
|
+
register: (command: DevToolsServerCommandInput) => DevToolsCommandHandle;
|
|
254
|
+
/**
|
|
255
|
+
* Unregister a command by ID (removes parent and all children).
|
|
256
|
+
*/
|
|
257
|
+
unregister: (id: string) => boolean;
|
|
258
|
+
/**
|
|
259
|
+
* Execute a command by ID. Searches top-level and children.
|
|
260
|
+
* Throws if not found or if command has no handler.
|
|
261
|
+
*/
|
|
262
|
+
execute: (id: string, ...args: any[]) => Promise<unknown>;
|
|
263
|
+
/**
|
|
264
|
+
* Returns serializable list (no handlers), preserving tree structure.
|
|
265
|
+
*/
|
|
266
|
+
list: () => DevToolsServerCommandEntry[];
|
|
267
|
+
}
|
|
268
|
+
interface DevToolsCommandShortcutOverrides {
|
|
269
|
+
/**
|
|
270
|
+
* Command ID → keybinding overrides. Empty array = shortcut disabled.
|
|
271
|
+
*/
|
|
272
|
+
[commandId: string]: DevToolsCommandKeybinding[];
|
|
273
|
+
}
|
|
274
|
+
//#endregion
|
|
153
275
|
//#region src/types/docks.d.ts
|
|
154
276
|
interface DevToolsDockHost {
|
|
155
277
|
readonly views: Map<string, DevToolsDockUserEntry>;
|
|
@@ -185,10 +307,16 @@ interface DevToolsDockEntryBase {
|
|
|
185
307
|
*/
|
|
186
308
|
category?: DevToolsDockEntryCategory;
|
|
187
309
|
/**
|
|
188
|
-
*
|
|
189
|
-
*
|
|
310
|
+
* Conditional visibility expression.
|
|
311
|
+
* When set, the dock entry is only visible when the expression evaluates to true.
|
|
312
|
+
* Uses the same syntax as command `when` clauses.
|
|
313
|
+
*
|
|
314
|
+
* Set to `'false'` to unconditionally hide the entry.
|
|
315
|
+
*
|
|
316
|
+
* @example 'clientType == embedded'
|
|
317
|
+
* @see {@link import('../utils/when').evaluateWhen}
|
|
190
318
|
*/
|
|
191
|
-
|
|
319
|
+
when?: string;
|
|
192
320
|
/**
|
|
193
321
|
* Badge text to display on the dock icon (e.g., unread count)
|
|
194
322
|
*/
|
|
@@ -414,6 +542,10 @@ interface DevToolsNodeContext {
|
|
|
414
542
|
* Logs host, for emitting and managing structured log entries
|
|
415
543
|
*/
|
|
416
544
|
logs: DevToolsLogsHost;
|
|
545
|
+
/**
|
|
546
|
+
* Commands host, for registering and executing commands
|
|
547
|
+
*/
|
|
548
|
+
commands: DevToolsCommandsHost;
|
|
417
549
|
/**
|
|
418
550
|
* Create a JsonRenderer handle for building json-render powered UIs.
|
|
419
551
|
* Pass the returned handle as `ui` when registering a `json-render` dock entry.
|
|
@@ -616,6 +748,21 @@ interface DocksContext extends DevToolsClientContext {
|
|
|
616
748
|
* The docks entries context
|
|
617
749
|
*/
|
|
618
750
|
readonly docks: DocksEntriesContext;
|
|
751
|
+
/**
|
|
752
|
+
* The commands context for command palette and shortcuts
|
|
753
|
+
*/
|
|
754
|
+
readonly commands: CommandsContext;
|
|
755
|
+
/**
|
|
756
|
+
* The when-clause context for conditional visibility
|
|
757
|
+
*/
|
|
758
|
+
readonly when: WhenClauseContext;
|
|
759
|
+
}
|
|
760
|
+
interface WhenClauseContext {
|
|
761
|
+
/**
|
|
762
|
+
* Get the current when-clause context snapshot.
|
|
763
|
+
* Returns a reactive object with built-in variables and any custom plugin variables.
|
|
764
|
+
*/
|
|
765
|
+
readonly context: WhenContext;
|
|
619
766
|
}
|
|
620
767
|
type DevToolsClientRpcHost = RpcFunctionsCollector<DevToolsRpcClientFunctions, DevToolsClientContext>;
|
|
621
768
|
interface DocksPanelContext {
|
|
@@ -667,6 +814,36 @@ interface DockEntryStateEvents {
|
|
|
667
814
|
interface RpcClientEvents {
|
|
668
815
|
'rpc:is-trusted:updated': (isTrusted: boolean) => void;
|
|
669
816
|
}
|
|
817
|
+
interface CommandsContext {
|
|
818
|
+
/**
|
|
819
|
+
* All commands (server + client)
|
|
820
|
+
*/
|
|
821
|
+
readonly commands: DevToolsCommandEntry[];
|
|
822
|
+
/**
|
|
823
|
+
* Palette-visible commands only (filtered by `showInPalette !== false`)
|
|
824
|
+
*/
|
|
825
|
+
readonly paletteCommands: DevToolsCommandEntry[];
|
|
826
|
+
/**
|
|
827
|
+
* Register client-side command(s). Returns cleanup function.
|
|
828
|
+
*/
|
|
829
|
+
register: (cmd: DevToolsClientCommand | DevToolsClientCommand[]) => () => void;
|
|
830
|
+
/**
|
|
831
|
+
* Execute a command by ID. Delegates to RPC for server commands.
|
|
832
|
+
*/
|
|
833
|
+
execute: (id: string, ...args: any[]) => Promise<unknown>;
|
|
834
|
+
/**
|
|
835
|
+
* Get effective keybindings for a command (defaults merged with overrides)
|
|
836
|
+
*/
|
|
837
|
+
getKeybindings: (id: string) => DevToolsCommandKeybinding[];
|
|
838
|
+
/**
|
|
839
|
+
* Shortcut overrides (persisted via shared state)
|
|
840
|
+
*/
|
|
841
|
+
shortcutOverrides: SharedState<DevToolsCommandShortcutOverrides>;
|
|
842
|
+
/**
|
|
843
|
+
* Whether the command palette is open
|
|
844
|
+
*/
|
|
845
|
+
paletteOpen: boolean;
|
|
846
|
+
}
|
|
670
847
|
//#endregion
|
|
671
848
|
//#region src/client/client-script.d.ts
|
|
672
849
|
/**
|
|
@@ -690,4 +867,4 @@ declare const CLIENT_CONTEXT_KEY = "__VITE_DEVTOOLS_CLIENT_CONTEXT__";
|
|
|
690
867
|
*/
|
|
691
868
|
declare function getDevToolsClientContext(): DevToolsClientContext | undefined;
|
|
692
869
|
//#endregion
|
|
693
|
-
export {
|
|
870
|
+
export { DevToolsDockEntriesGrouped as $, DevToolsNodeRpcSession as A, DevToolsLogFilePosition as At, DevToolsPluginOptions as B, RpcDefinitionsFilter as C, DevToolsCommandsHostEvents as Ct, PartialWithoutId as D, DevToolsLogEntry as Dt, EntriesToObject as E, DevToolsLogElementPosition as Et, RpcSharedStateHost as F, DevToolsTerminalSession as G, DevToolsChildProcessExecuteOptions as H, ConnectionMeta as I, DevToolsTerminalStatus as J, DevToolsTerminalSessionBase as K, DevToolsCapabilities as L, RpcBroadcastOptions as M, DevToolsLogLevel as Mt, RpcFunctionsHost as N, DevToolsLogsClient as Nt, Thenable as O, DevToolsLogEntryFrom as Ot, RpcSharedStateGetOptions as P, DevToolsLogsHost as Pt, ClientScriptEntry as Q, DevToolsNodeContext as R, getDevToolsRpcClient as S, DevToolsCommandsHost as St, PluginWithDevTools as T, DevToolsServerCommandInput as Tt, DevToolsChildProcessTerminalSession as U, DevToolsViewHost as V, DevToolsTerminalHost as W, DevToolsRpcServerFunctions as X, DevToolsRpcClientFunctions as Y, DevToolsRpcSharedStates as Z, DevToolsRpcClientCall as _, DevToolsCommandBase as _t, DevToolsClientContext as a, DevToolsDockUserEntry as at, DevToolsRpcClientMode as b, DevToolsCommandKeybinding as bt, DockEntryState as c, DevToolsViewCustomRender as ct, DocksContext as d, DevToolsViewLauncher as dt, DevToolsDockEntry as et, DocksEntriesContext as f, DevToolsViewLauncherStatus as ft, DevToolsRpcClient as g, DevToolsClientCommand as gt, WhenClauseContext as h, JsonRenderer as ht, CommandsContext as i, DevToolsDockHost as it, DevToolsNodeRpcSessionMeta as j, DevToolsLogHandle as jt, DevToolsDocksUserSettings as k, DevToolsLogEntryInput as kt, DockEntryStateEvents as l, DevToolsViewIframe as lt, RpcClientEvents as m, JsonRenderSpec as mt, getDevToolsClientContext as n, DevToolsDockEntryCategory as nt, DevToolsClientRpcHost as o, DevToolsViewAction as ot, DocksPanelContext as p, JsonRenderElement as pt, DevToolsTerminalSessionStreamChunkEvent as q, DockClientScriptContext as r, DevToolsDockEntryIcon as rt, DockClientType as s, DevToolsViewBuiltin as st, CLIENT_CONTEXT_KEY as t, DevToolsDockEntryBase as tt, DockPanelStorage as u, DevToolsViewJsonRender as ut, DevToolsRpcClientCallEvent as v, DevToolsCommandEntry as vt, RpcDefinitionsToFunctions as w, DevToolsServerCommandEntry as wt, DevToolsRpcClientOptions as x, DevToolsCommandShortcutOverrides as xt, DevToolsRpcClientCallOptional as y, DevToolsCommandHandle as yt, DevToolsNodeUtils as z };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { n as EventUnsubscribe, r as EventsMap, t as EventEmitter } from "./events-BTCXlxeC.js";
|
|
2
|
-
import { $ as
|
|
2
|
+
import { $ as DevToolsDockEntriesGrouped, A as DevToolsNodeRpcSession, At as DevToolsLogFilePosition, B as DevToolsPluginOptions, C as RpcDefinitionsFilter, Ct as DevToolsCommandsHostEvents, D as PartialWithoutId, Dt as DevToolsLogEntry, E as EntriesToObject, Et as DevToolsLogElementPosition, F as RpcSharedStateHost, G as DevToolsTerminalSession, H as DevToolsChildProcessExecuteOptions, I as ConnectionMeta, J as DevToolsTerminalStatus, K as DevToolsTerminalSessionBase, L as DevToolsCapabilities, M as RpcBroadcastOptions, Mt as DevToolsLogLevel, N as RpcFunctionsHost, Nt as DevToolsLogsClient, O as Thenable, Ot as DevToolsLogEntryFrom, P as RpcSharedStateGetOptions, Pt as DevToolsLogsHost, Q as ClientScriptEntry, R as DevToolsNodeContext, St as DevToolsCommandsHost, T as PluginWithDevTools, Tt as DevToolsServerCommandInput, U as DevToolsChildProcessTerminalSession, V as DevToolsViewHost, W as DevToolsTerminalHost, X as DevToolsRpcServerFunctions, Y as DevToolsRpcClientFunctions, Z as DevToolsRpcSharedStates, _t as DevToolsCommandBase, at as DevToolsDockUserEntry, bt as DevToolsCommandKeybinding, ct as DevToolsViewCustomRender, dt as DevToolsViewLauncher, et as DevToolsDockEntry, ft as DevToolsViewLauncherStatus, gt as DevToolsClientCommand, ht as JsonRenderer, it as DevToolsDockHost, j as DevToolsNodeRpcSessionMeta, jt as DevToolsLogHandle, k as DevToolsDocksUserSettings, kt as DevToolsLogEntryInput, lt as DevToolsViewIframe, mt as JsonRenderSpec, nt as DevToolsDockEntryCategory, ot as DevToolsViewAction, pt as JsonRenderElement, q as DevToolsTerminalSessionStreamChunkEvent, rt as DevToolsDockEntryIcon, st as DevToolsViewBuiltin, tt as DevToolsDockEntryBase, ut as DevToolsViewJsonRender, vt as DevToolsCommandEntry, w as RpcDefinitionsToFunctions, wt as DevToolsServerCommandEntry, xt as DevToolsCommandShortcutOverrides, yt as DevToolsCommandHandle, z as DevToolsNodeUtils } from "./index-BMTnY3zc.js";
|
|
3
|
+
import { t as WhenContext } from "./when-snfIizvo.js";
|
|
3
4
|
import * as _vitejs_devtools_rpc0 from "@vitejs/devtools-rpc";
|
|
4
5
|
|
|
5
|
-
//#region src/
|
|
6
|
+
//#region src/define.d.ts
|
|
6
7
|
declare const defineRpcFunction: <NAME extends string, TYPE extends _vitejs_devtools_rpc0.RpcFunctionType, ARGS extends any[], RETURN = void, const AS extends _vitejs_devtools_rpc0.RpcArgsSchema | undefined = undefined, const RS extends _vitejs_devtools_rpc0.RpcReturnSchema | undefined = undefined>(definition: _vitejs_devtools_rpc0.RpcFunctionDefinition<NAME, TYPE, ARGS, RETURN, AS, RS, DevToolsNodeContext>) => _vitejs_devtools_rpc0.RpcFunctionDefinition<NAME, TYPE, ARGS, RETURN, AS, RS, DevToolsNodeContext>;
|
|
7
|
-
|
|
8
|
-
//#region src/utils/json-render.d.ts
|
|
8
|
+
declare function defineCommand(command: DevToolsServerCommandInput): DevToolsServerCommandInput;
|
|
9
9
|
declare function defineJsonRenderSpec(spec: JsonRenderSpec): JsonRenderSpec;
|
|
10
10
|
//#endregion
|
|
11
|
-
export { ClientScriptEntry, ConnectionMeta, DevToolsCapabilities, DevToolsChildProcessExecuteOptions, DevToolsChildProcessTerminalSession, DevToolsDockEntriesGrouped, DevToolsDockEntry, DevToolsDockEntryBase, DevToolsDockEntryCategory, DevToolsDockEntryIcon, DevToolsDockHost, DevToolsDockUserEntry, DevToolsDocksUserSettings, DevToolsLogElementPosition, DevToolsLogEntry, DevToolsLogEntryFrom, DevToolsLogEntryInput, DevToolsLogFilePosition, DevToolsLogHandle, DevToolsLogLevel, DevToolsLogsClient, DevToolsLogsHost, DevToolsNodeContext, DevToolsNodeRpcSession, DevToolsNodeRpcSessionMeta, DevToolsNodeUtils, DevToolsPluginOptions, DevToolsRpcClientFunctions, DevToolsRpcServerFunctions, DevToolsRpcSharedStates, DevToolsTerminalHost, DevToolsTerminalSession, DevToolsTerminalSessionBase, DevToolsTerminalSessionStreamChunkEvent, DevToolsTerminalStatus, DevToolsViewAction, DevToolsViewBuiltin, DevToolsViewCustomRender, DevToolsViewHost, DevToolsViewIframe, DevToolsViewJsonRender, DevToolsViewLauncher, DevToolsViewLauncherStatus, EntriesToObject, EventEmitter, EventUnsubscribe, EventsMap, JsonRenderElement, JsonRenderSpec, JsonRenderer, PartialWithoutId, PluginWithDevTools, RpcBroadcastOptions, RpcDefinitionsFilter, RpcDefinitionsToFunctions, RpcFunctionsHost, RpcSharedStateGetOptions, RpcSharedStateHost, Thenable, defineJsonRenderSpec, defineRpcFunction };
|
|
11
|
+
export { ClientScriptEntry, ConnectionMeta, DevToolsCapabilities, DevToolsChildProcessExecuteOptions, DevToolsChildProcessTerminalSession, DevToolsClientCommand, DevToolsCommandBase, DevToolsCommandEntry, DevToolsCommandHandle, DevToolsCommandKeybinding, DevToolsCommandShortcutOverrides, DevToolsCommandsHost, DevToolsCommandsHostEvents, DevToolsDockEntriesGrouped, DevToolsDockEntry, DevToolsDockEntryBase, DevToolsDockEntryCategory, DevToolsDockEntryIcon, DevToolsDockHost, DevToolsDockUserEntry, DevToolsDocksUserSettings, DevToolsLogElementPosition, DevToolsLogEntry, DevToolsLogEntryFrom, DevToolsLogEntryInput, DevToolsLogFilePosition, DevToolsLogHandle, DevToolsLogLevel, DevToolsLogsClient, DevToolsLogsHost, DevToolsNodeContext, DevToolsNodeRpcSession, DevToolsNodeRpcSessionMeta, DevToolsNodeUtils, DevToolsPluginOptions, DevToolsRpcClientFunctions, DevToolsRpcServerFunctions, DevToolsRpcSharedStates, DevToolsServerCommandEntry, DevToolsServerCommandInput, DevToolsTerminalHost, DevToolsTerminalSession, DevToolsTerminalSessionBase, DevToolsTerminalSessionStreamChunkEvent, DevToolsTerminalStatus, DevToolsViewAction, DevToolsViewBuiltin, DevToolsViewCustomRender, DevToolsViewHost, DevToolsViewIframe, DevToolsViewJsonRender, DevToolsViewLauncher, DevToolsViewLauncherStatus, EntriesToObject, EventEmitter, EventUnsubscribe, EventsMap, JsonRenderElement, JsonRenderSpec, JsonRenderer, PartialWithoutId, PluginWithDevTools, RpcBroadcastOptions, RpcDefinitionsFilter, RpcDefinitionsToFunctions, RpcFunctionsHost, RpcSharedStateGetOptions, RpcSharedStateHost, Thenable, WhenContext, defineCommand, defineJsonRenderSpec, defineRpcFunction };
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { createDefineWrapperWithContext } from "@vitejs/devtools-rpc";
|
|
2
|
-
//#region src/
|
|
2
|
+
//#region src/define.ts
|
|
3
3
|
const defineRpcFunction = createDefineWrapperWithContext();
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
function defineCommand(command) {
|
|
5
|
+
return command;
|
|
6
|
+
}
|
|
6
7
|
function defineJsonRenderSpec(spec) {
|
|
7
8
|
return spec;
|
|
8
9
|
}
|
|
9
10
|
//#endregion
|
|
10
|
-
export { defineJsonRenderSpec, defineRpcFunction };
|
|
11
|
+
export { defineCommand, defineJsonRenderSpec, defineRpcFunction };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as ImmutableSet, c as SharedStateOptions, i as ImmutableObject, l as createSharedState, n as ImmutableArray, o as SharedState, r as ImmutableMap, s as SharedStateEvents, t as Immutable, u as Patch } from "../shared-state-
|
|
1
|
+
import { a as ImmutableSet, c as SharedStateOptions, i as ImmutableObject, l as createSharedState, n as ImmutableArray, o as SharedState, r as ImmutableMap, s as SharedStateEvents, t as Immutable, u as Patch } from "../shared-state-CQAciU8Y.js";
|
|
2
2
|
export { Immutable, ImmutableArray, ImmutableMap, ImmutableObject, ImmutableSet, SharedState, SharedStateEvents, SharedStateOptions, Patch as SharedStatePatch, createSharedState };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
//#region src/utils/when.ts
|
|
2
|
+
/**
|
|
3
|
+
* Evaluate a `when` expression against a context object.
|
|
4
|
+
*
|
|
5
|
+
* Supported syntax:
|
|
6
|
+
* - Bare truthy: `dockOpen` → true if value is truthy
|
|
7
|
+
* - Literal booleans: `true`, `false`
|
|
8
|
+
* - Negation: `!paletteOpen`
|
|
9
|
+
* - Equality: `clientType == embedded`
|
|
10
|
+
* - Inequality: `clientType != standalone`
|
|
11
|
+
* - AND: `dockOpen && !paletteOpen`
|
|
12
|
+
* - OR: `paletteOpen || dockOpen`
|
|
13
|
+
* - Namespaced keys: `vite.mode == development`, `vite:buildMode`
|
|
14
|
+
*
|
|
15
|
+
* Precedence: `||` (lowest) → `&&` → unary `!`
|
|
16
|
+
*/
|
|
17
|
+
function evaluateWhen(expression, ctx) {
|
|
18
|
+
return expression.split("||").map((s) => s.trim()).some((orPart) => {
|
|
19
|
+
return orPart.split("&&").map((s) => s.trim()).every((part) => {
|
|
20
|
+
const trimmed = part.trim();
|
|
21
|
+
if (trimmed === "true") return true;
|
|
22
|
+
if (trimmed === "false") return false;
|
|
23
|
+
if (trimmed.startsWith("!")) {
|
|
24
|
+
const key = trimmed.slice(1).trim();
|
|
25
|
+
if (key === "true") return false;
|
|
26
|
+
if (key === "false") return true;
|
|
27
|
+
return !getContextValue(key, ctx);
|
|
28
|
+
}
|
|
29
|
+
const eqIdx = trimmed.indexOf("==");
|
|
30
|
+
const neqIdx = trimmed.indexOf("!=");
|
|
31
|
+
if (eqIdx !== -1 || neqIdx !== -1) {
|
|
32
|
+
const isNeq = neqIdx !== -1 && (eqIdx === -1 || neqIdx < eqIdx);
|
|
33
|
+
const opIdx = isNeq ? neqIdx : eqIdx;
|
|
34
|
+
const opLen = isNeq ? 2 : 2;
|
|
35
|
+
const key = trimmed.slice(0, opIdx).trim();
|
|
36
|
+
const value = trimmed.slice(opIdx + opLen).trim();
|
|
37
|
+
const actual = String(getContextValue(key, ctx));
|
|
38
|
+
return isNeq ? actual !== value : actual === value;
|
|
39
|
+
}
|
|
40
|
+
return !!getContextValue(trimmed, ctx);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Get a context value by key. Supports namespaced keys with `.` or `:` separators.
|
|
46
|
+
*
|
|
47
|
+
* Lookup order:
|
|
48
|
+
* 1. Exact match — `ctx['vite.mode']` or `ctx['vite:mode']`
|
|
49
|
+
* 2. Nested path — for `vite.mode`: `ctx.vite?.mode`; for `vite:mode`: `ctx.vite?.mode`
|
|
50
|
+
*/
|
|
51
|
+
function getContextValue(key, ctx) {
|
|
52
|
+
const record = ctx;
|
|
53
|
+
if (key in record) return record[key];
|
|
54
|
+
const separator = key.includes(".") ? "." : key.includes(":") ? ":" : null;
|
|
55
|
+
if (separator) {
|
|
56
|
+
const segments = key.split(separator);
|
|
57
|
+
let current = record;
|
|
58
|
+
for (const segment of segments) {
|
|
59
|
+
if (current == null || typeof current !== "object") return void 0;
|
|
60
|
+
current = current[segment];
|
|
61
|
+
}
|
|
62
|
+
return current;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
//#endregion
|
|
66
|
+
export { evaluateWhen, getContextValue };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
//#region src/utils/when.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Context object for evaluating `when` expressions.
|
|
4
|
+
*
|
|
5
|
+
* Built-in variables:
|
|
6
|
+
* - `clientType` — `'embedded' | 'standalone'`
|
|
7
|
+
* - `dockOpen` — whether the dock panel is open
|
|
8
|
+
* - `paletteOpen` — whether the command palette is open
|
|
9
|
+
* - `dockSelectedId` — ID of the selected dock entry (empty string if none)
|
|
10
|
+
*
|
|
11
|
+
* Plugins can add namespaced variables using dot or colon separators:
|
|
12
|
+
* - `vite.mode`, `vite:mode` — stored as `{ 'vite.mode': 'development' }` or nested `{ vite: { mode: 'development' } }`
|
|
13
|
+
*/
|
|
14
|
+
interface WhenContext {
|
|
15
|
+
clientType: 'embedded' | 'standalone';
|
|
16
|
+
dockOpen: boolean;
|
|
17
|
+
paletteOpen: boolean;
|
|
18
|
+
dockSelectedId: string;
|
|
19
|
+
/** Allow custom context variables from plugins */
|
|
20
|
+
[key: string]: unknown;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Evaluate a `when` expression against a context object.
|
|
24
|
+
*
|
|
25
|
+
* Supported syntax:
|
|
26
|
+
* - Bare truthy: `dockOpen` → true if value is truthy
|
|
27
|
+
* - Literal booleans: `true`, `false`
|
|
28
|
+
* - Negation: `!paletteOpen`
|
|
29
|
+
* - Equality: `clientType == embedded`
|
|
30
|
+
* - Inequality: `clientType != standalone`
|
|
31
|
+
* - AND: `dockOpen && !paletteOpen`
|
|
32
|
+
* - OR: `paletteOpen || dockOpen`
|
|
33
|
+
* - Namespaced keys: `vite.mode == development`, `vite:buildMode`
|
|
34
|
+
*
|
|
35
|
+
* Precedence: `||` (lowest) → `&&` → unary `!`
|
|
36
|
+
*/
|
|
37
|
+
declare function evaluateWhen(expression: string, ctx: WhenContext): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Get a context value by key. Supports namespaced keys with `.` or `:` separators.
|
|
40
|
+
*
|
|
41
|
+
* Lookup order:
|
|
42
|
+
* 1. Exact match — `ctx['vite.mode']` or `ctx['vite:mode']`
|
|
43
|
+
* 2. Nested path — for `vite.mode`: `ctx.vite?.mode`; for `vite:mode`: `ctx.vite?.mode`
|
|
44
|
+
*/
|
|
45
|
+
declare function getContextValue(key: string, ctx: WhenContext): unknown;
|
|
46
|
+
//#endregion
|
|
47
|
+
export { evaluateWhen as n, getContextValue as r, WhenContext as t };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vitejs/devtools-kit",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.9",
|
|
5
5
|
"description": "Vite DevTools Kit",
|
|
6
6
|
"author": "VoidZero Inc.",
|
|
7
7
|
"license": "MIT",
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
"./utils/human-id": "./dist/utils/human-id.js",
|
|
27
27
|
"./utils/nanoid": "./dist/utils/nanoid.js",
|
|
28
28
|
"./utils/shared-state": "./dist/utils/shared-state.js",
|
|
29
|
+
"./utils/when": "./dist/utils/when.js",
|
|
29
30
|
"./package.json": "./package.json"
|
|
30
31
|
},
|
|
31
32
|
"types": "./dist/index.d.mts",
|
|
@@ -39,14 +40,14 @@
|
|
|
39
40
|
"dependencies": {
|
|
40
41
|
"birpc": "^4.0.0",
|
|
41
42
|
"ohash": "^2.0.11",
|
|
42
|
-
"@vitejs/devtools-rpc": "0.1.
|
|
43
|
+
"@vitejs/devtools-rpc": "0.1.9"
|
|
43
44
|
},
|
|
44
45
|
"devDependencies": {
|
|
45
46
|
"human-id": "^4.1.3",
|
|
46
47
|
"immer": "^11.1.4",
|
|
47
48
|
"tsdown": "^0.21.4",
|
|
48
49
|
"ua-parser-modern": "^0.1.1",
|
|
49
|
-
"vite": "^8.0.
|
|
50
|
+
"vite": "^8.0.2"
|
|
50
51
|
},
|
|
51
52
|
"inlinedDependencies": {
|
|
52
53
|
"human-id": "4.1.3",
|
|
@@ -25,6 +25,7 @@ A DevTools plugin extends a Vite plugin with a `devtools.setup(ctx)` hook. The c
|
|
|
25
25
|
| `ctx.logs` | Emit structured log entries and toast notifications |
|
|
26
26
|
| `ctx.terminals` | Spawn and manage child processes with streaming terminal output |
|
|
27
27
|
| `ctx.createJsonRenderer` | Create server-side JSON render specs for zero-client-code UIs |
|
|
28
|
+
| `ctx.commands` | Register executable commands with keyboard shortcuts and palette visibility |
|
|
28
29
|
| `ctx.viteConfig` | Resolved Vite configuration |
|
|
29
30
|
| `ctx.viteServer` | Dev server instance (dev mode only) |
|
|
30
31
|
| `ctx.mode` | `'dev'` or `'build'` |
|
|
@@ -107,12 +108,13 @@ export default function myAnalyzer(): Plugin {
|
|
|
107
108
|
|
|
108
109
|
## Namespacing Convention
|
|
109
110
|
|
|
110
|
-
**CRITICAL**: Always prefix RPC functions, shared state keys, and
|
|
111
|
+
**CRITICAL**: Always prefix RPC functions, shared state keys, dock IDs, and command IDs with your plugin name:
|
|
111
112
|
|
|
112
113
|
```ts
|
|
113
114
|
// Good - namespaced
|
|
114
115
|
'my-plugin:get-modules'
|
|
115
116
|
'my-plugin:state'
|
|
117
|
+
'my-plugin:clear-cache' // command ID
|
|
116
118
|
|
|
117
119
|
// Bad - may conflict
|
|
118
120
|
'get-modules'
|
|
@@ -254,6 +256,27 @@ await session.restart()
|
|
|
254
256
|
|
|
255
257
|
A common pattern is combining with launcher docks — see [Terminals Patterns](./references/terminals-patterns.md).
|
|
256
258
|
|
|
259
|
+
## Commands & Command Palette
|
|
260
|
+
|
|
261
|
+
Register executable commands discoverable via `Mod+K` palette:
|
|
262
|
+
|
|
263
|
+
```ts
|
|
264
|
+
import { defineCommand } from '@vitejs/devtools-kit'
|
|
265
|
+
|
|
266
|
+
ctx.commands.register(defineCommand({
|
|
267
|
+
id: 'my-plugin:clear-cache',
|
|
268
|
+
title: 'Clear Build Cache',
|
|
269
|
+
icon: 'ph:trash-duotone',
|
|
270
|
+
keybindings: [{ key: 'Mod+Shift+C' }],
|
|
271
|
+
when: 'clientType == embedded',
|
|
272
|
+
handler: async () => { /* ... */ },
|
|
273
|
+
}))
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
Commands support sub-commands (two-level hierarchy), conditional visibility via `when` clauses, and user-customizable keyboard shortcuts.
|
|
277
|
+
|
|
278
|
+
See [Commands Patterns](./references/commands-patterns.md) and [When Clauses](./references/when-clauses.md) for full details.
|
|
279
|
+
|
|
257
280
|
## Logs & Notifications
|
|
258
281
|
|
|
259
282
|
Plugins can emit structured log entries from both server and client contexts. Logs appear in the built-in **Logs** panel and can optionally show as toast notifications.
|
|
@@ -498,6 +521,8 @@ export default defineConfig({
|
|
|
498
521
|
6. **Use Iconify icons** - Prefer `ph:*` (Phosphor) icons: `icon: 'ph:chart-bar-duotone'`
|
|
499
522
|
7. **Deduplicate logs** - Use explicit `id` for logs representing ongoing operations
|
|
500
523
|
8. **Use Self-Inspect** - Add `@vitejs/devtools-self-inspect` during development to debug your plugin
|
|
524
|
+
9. **Namespace command IDs** - Use `my-plugin:action` pattern for command IDs, same as RPC and state
|
|
525
|
+
10. **Use `when` clauses** - Conditionally show commands/docks with `when` expressions instead of programmatic show/hide
|
|
501
526
|
|
|
502
527
|
## Example Plugins
|
|
503
528
|
|
|
@@ -516,3 +541,5 @@ Real-world example plugins in the repo — reference their code structure and pa
|
|
|
516
541
|
- [JSON Render Patterns](./references/json-render-patterns.md) - Server-side JSON specs, components, state binding
|
|
517
542
|
- [Terminals Patterns](./references/terminals-patterns.md) - Child processes, custom streams, session lifecycle
|
|
518
543
|
- [Logs Patterns](./references/logs-patterns.md) - Log entries, toast notifications, and handle patterns
|
|
544
|
+
- [Commands Patterns](./references/commands-patterns.md) - Command registration, sub-commands, keybindings, palette integration
|
|
545
|
+
- [When Clauses](./references/when-clauses.md) - Conditional expression syntax, context variables, API reference
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
# Commands & Command Palette
|
|
2
|
+
|
|
3
|
+
Register executable commands discoverable through a built-in palette with keyboard shortcuts.
|
|
4
|
+
|
|
5
|
+
## Defining Commands
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { defineCommand } from '@vitejs/devtools-kit'
|
|
9
|
+
|
|
10
|
+
const clearCache = defineCommand({
|
|
11
|
+
id: 'my-plugin:clear-cache',
|
|
12
|
+
title: 'Clear Build Cache',
|
|
13
|
+
description: 'Remove all cached build artifacts',
|
|
14
|
+
icon: 'ph:trash-duotone',
|
|
15
|
+
category: 'tools',
|
|
16
|
+
handler: async () => {
|
|
17
|
+
await fs.rm('.cache', { recursive: true })
|
|
18
|
+
},
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
// Register in plugin setup
|
|
22
|
+
ctx.commands.register(clearCache)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Command Options
|
|
26
|
+
|
|
27
|
+
| Field | Type | Description |
|
|
28
|
+
|-------|------|-------------|
|
|
29
|
+
| `id` | `string` | **Required.** Unique namespaced ID (e.g. `my-plugin:action`) |
|
|
30
|
+
| `title` | `string` | **Required.** Human-readable title shown in the palette |
|
|
31
|
+
| `description` | `string` | Optional description text |
|
|
32
|
+
| `icon` | `string` | Iconify icon string (e.g. `ph:trash-duotone`) |
|
|
33
|
+
| `category` | `string` | Category for grouping |
|
|
34
|
+
| `showInPalette` | `boolean \| 'without-children'` | Whether to show in command palette (default: `true`). `'without-children'` shows the command but doesn't flatten children into search — only accessible via drill-down. |
|
|
35
|
+
| `when` | `string` | Conditional visibility expression — see [When Clauses](./when-clauses.md) |
|
|
36
|
+
| `keybindings` | `DevToolsCommandKeybinding[]` | Default keyboard shortcuts |
|
|
37
|
+
| `handler` | `Function` | Server-side handler. Optional if the command is a group for children. |
|
|
38
|
+
| `children` | `DevToolsServerCommandInput[]` | Static sub-commands (two levels max) |
|
|
39
|
+
|
|
40
|
+
## Command Handle
|
|
41
|
+
|
|
42
|
+
`register()` returns a handle for live updates:
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
const handle = ctx.commands.register({
|
|
46
|
+
id: 'my-plugin:status',
|
|
47
|
+
title: 'Show Status',
|
|
48
|
+
handler: () => { /* ... */ },
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
// Update later
|
|
52
|
+
handle.update({ title: 'Show Status (3 items)' })
|
|
53
|
+
|
|
54
|
+
// Remove
|
|
55
|
+
handle.unregister()
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Sub-Commands
|
|
59
|
+
|
|
60
|
+
Two-level hierarchy. Selecting a parent in the palette drills down into its children.
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
ctx.commands.register({
|
|
64
|
+
id: 'git',
|
|
65
|
+
title: 'Git',
|
|
66
|
+
icon: 'ph:git-branch-duotone',
|
|
67
|
+
category: 'tools',
|
|
68
|
+
// No handler — group-only parent
|
|
69
|
+
children: [
|
|
70
|
+
{
|
|
71
|
+
id: 'git:commit',
|
|
72
|
+
title: 'Commit',
|
|
73
|
+
icon: 'ph:check-duotone',
|
|
74
|
+
keybindings: [{ key: 'Mod+Shift+G' }],
|
|
75
|
+
handler: async () => { /* ... */ },
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
id: 'git:push',
|
|
79
|
+
title: 'Push',
|
|
80
|
+
handler: async () => { /* ... */ },
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
})
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Each child must have a globally unique `id`. Use the pattern `parentId:childAction` (e.g. `git:commit`).
|
|
87
|
+
|
|
88
|
+
Sub-commands with keybindings can be executed directly via the shortcut without opening the palette.
|
|
89
|
+
|
|
90
|
+
## Keyboard Shortcuts
|
|
91
|
+
|
|
92
|
+
### Key Format
|
|
93
|
+
|
|
94
|
+
Use `Mod` as a platform-aware modifier — maps to `Cmd` on macOS and `Ctrl` on other platforms.
|
|
95
|
+
|
|
96
|
+
| Key string | macOS | Windows/Linux |
|
|
97
|
+
|------------|-------|---------------|
|
|
98
|
+
| `Mod+K` | `Cmd+K` | `Ctrl+K` |
|
|
99
|
+
| `Mod+Shift+P` | `Cmd+Shift+P` | `Ctrl+Shift+P` |
|
|
100
|
+
| `Alt+N` | `Option+N` | `Alt+N` |
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
ctx.commands.register(defineCommand({
|
|
104
|
+
id: 'my-plugin:toggle-overlay',
|
|
105
|
+
title: 'Toggle Overlay',
|
|
106
|
+
keybindings: [{ key: 'Mod+Shift+O' }],
|
|
107
|
+
handler: () => { /* ... */ },
|
|
108
|
+
}))
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### User Overrides
|
|
112
|
+
|
|
113
|
+
Users can customize shortcuts in Settings > **Keyboard Shortcuts**. Overrides persist across sessions. Setting an empty array disables a shortcut.
|
|
114
|
+
|
|
115
|
+
The shortcut editor includes:
|
|
116
|
+
- **Key capture** — click the input and press any key combination
|
|
117
|
+
- **Modifier toggles** — toggle Cmd/Ctrl, Alt, Shift individually
|
|
118
|
+
- **Conflict detection** — warns on browser shortcut conflicts, duplicate bindings, and weak shortcuts (single key without modifiers)
|
|
119
|
+
|
|
120
|
+
`KNOWN_BROWSER_SHORTCUTS` is exported from `@vitejs/devtools-kit` and maps key combinations to human-readable descriptions.
|
|
121
|
+
|
|
122
|
+
## Conditional Visibility
|
|
123
|
+
|
|
124
|
+
Commands support a `when` expression for conditional visibility:
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
ctx.commands.register(defineCommand({
|
|
128
|
+
id: 'my-plugin:embedded-only',
|
|
129
|
+
title: 'Embedded-Only Action',
|
|
130
|
+
when: 'clientType == embedded',
|
|
131
|
+
handler: async () => { /* ... */ },
|
|
132
|
+
}))
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
When set, the command only appears in the palette and is only triggerable via shortcuts when the expression evaluates to `true`.
|
|
136
|
+
|
|
137
|
+
See [When Clauses](./when-clauses.md) for full syntax reference and context variables.
|
|
138
|
+
|
|
139
|
+
## Client-Side Commands
|
|
140
|
+
|
|
141
|
+
Client commands register in the webcomponent context and execute directly in the browser:
|
|
142
|
+
|
|
143
|
+
```ts
|
|
144
|
+
context.commands.register({
|
|
145
|
+
id: 'devtools:theme',
|
|
146
|
+
source: 'client',
|
|
147
|
+
title: 'Theme',
|
|
148
|
+
icon: 'ph:palette-duotone',
|
|
149
|
+
children: [
|
|
150
|
+
{
|
|
151
|
+
id: 'devtools:theme:light',
|
|
152
|
+
source: 'client',
|
|
153
|
+
title: 'Light',
|
|
154
|
+
action: () => setTheme('light'),
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
id: 'devtools:theme:dark',
|
|
158
|
+
source: 'client',
|
|
159
|
+
title: 'Dark',
|
|
160
|
+
action: () => setTheme('dark'),
|
|
161
|
+
},
|
|
162
|
+
],
|
|
163
|
+
})
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Client commands can return dynamic sub-items:
|
|
167
|
+
|
|
168
|
+
```ts
|
|
169
|
+
context.commands.register({
|
|
170
|
+
id: 'devtools:docs',
|
|
171
|
+
source: 'client',
|
|
172
|
+
title: 'Documentation',
|
|
173
|
+
action: async () => {
|
|
174
|
+
const docs = await fetchDocs()
|
|
175
|
+
return docs.map(doc => ({
|
|
176
|
+
id: `docs:${doc.slug}`,
|
|
177
|
+
source: 'client' as const,
|
|
178
|
+
title: doc.title,
|
|
179
|
+
action: () => window.open(doc.url, '_blank'),
|
|
180
|
+
}))
|
|
181
|
+
},
|
|
182
|
+
})
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## Command Palette
|
|
186
|
+
|
|
187
|
+
Built-in palette toggled with `Mod+K`. Features:
|
|
188
|
+
|
|
189
|
+
- **Fuzzy search** across all registered commands (including sub-commands)
|
|
190
|
+
- **Keyboard navigation** — Arrow keys, Enter to select, Escape to close
|
|
191
|
+
- **Drill-down** — Commands with children show breadcrumb navigation
|
|
192
|
+
- **Server command execution** — via RPC with loading indicator
|
|
193
|
+
- **Dynamic sub-menus** — Client commands can return sub-items at runtime
|
|
194
|
+
|
|
195
|
+
## Complete Example
|
|
196
|
+
|
|
197
|
+
```ts
|
|
198
|
+
/// <reference types="@vitejs/devtools-kit" />
|
|
199
|
+
import type { Plugin } from 'vite'
|
|
200
|
+
import { defineCommand } from '@vitejs/devtools-kit'
|
|
201
|
+
|
|
202
|
+
export default function myPlugin(): Plugin {
|
|
203
|
+
return {
|
|
204
|
+
name: 'my-plugin',
|
|
205
|
+
|
|
206
|
+
devtools: {
|
|
207
|
+
setup(ctx) {
|
|
208
|
+
// Simple command with keybinding
|
|
209
|
+
ctx.commands.register(defineCommand({
|
|
210
|
+
id: 'my-plugin:restart',
|
|
211
|
+
title: 'Restart Dev Server',
|
|
212
|
+
icon: 'ph:arrow-clockwise-duotone',
|
|
213
|
+
keybindings: [{ key: 'Mod+Shift+R' }],
|
|
214
|
+
handler: async () => {
|
|
215
|
+
await ctx.viteServer?.restart()
|
|
216
|
+
},
|
|
217
|
+
}))
|
|
218
|
+
|
|
219
|
+
// Command group with sub-commands
|
|
220
|
+
ctx.commands.register(defineCommand({
|
|
221
|
+
id: 'my-plugin:cache',
|
|
222
|
+
title: 'Cache',
|
|
223
|
+
icon: 'ph:database-duotone',
|
|
224
|
+
children: [
|
|
225
|
+
{
|
|
226
|
+
id: 'my-plugin:cache:clear',
|
|
227
|
+
title: 'Clear Cache',
|
|
228
|
+
handler: async () => { /* ... */ },
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
id: 'my-plugin:cache:inspect',
|
|
232
|
+
title: 'Inspect Cache',
|
|
233
|
+
handler: async () => { /* ... */ },
|
|
234
|
+
},
|
|
235
|
+
],
|
|
236
|
+
}))
|
|
237
|
+
},
|
|
238
|
+
},
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
```
|
|
@@ -13,7 +13,7 @@ interface DockEntryBase {
|
|
|
13
13
|
icon: string // URL, data URI, or Iconify name
|
|
14
14
|
category?: string // Grouping category
|
|
15
15
|
defaultOrder?: number // Sort order (higher = earlier)
|
|
16
|
-
|
|
16
|
+
when?: string // Conditional visibility expression — see [When Clauses](./when-clauses.md)
|
|
17
17
|
badge?: string // Badge text on dock icon (e.g., count)
|
|
18
18
|
}
|
|
19
19
|
```
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# When Clauses
|
|
2
|
+
|
|
3
|
+
Conditional expressions controlling visibility and activation of commands and dock entries.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
### On Commands
|
|
8
|
+
|
|
9
|
+
Controls whether the command appears in the palette and can be triggered via shortcuts:
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
ctx.commands.register(defineCommand({
|
|
13
|
+
id: 'my-plugin:embedded-only',
|
|
14
|
+
title: 'Embedded-Only Action',
|
|
15
|
+
when: 'clientType == embedded',
|
|
16
|
+
handler: async () => { /* ... */ },
|
|
17
|
+
}))
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### On Dock Entries
|
|
21
|
+
|
|
22
|
+
Controls whether a dock entry is visible in the dock bar:
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
ctx.docks.register({
|
|
26
|
+
id: 'my-plugin:inspector',
|
|
27
|
+
title: 'Inspector',
|
|
28
|
+
type: 'action',
|
|
29
|
+
icon: 'ph:cursor-duotone',
|
|
30
|
+
when: 'clientType == embedded',
|
|
31
|
+
action: { importFrom: 'my-plugin/inspector' },
|
|
32
|
+
})
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Set `when: 'false'` to unconditionally hide a dock entry.
|
|
36
|
+
|
|
37
|
+
## Expression Syntax
|
|
38
|
+
|
|
39
|
+
### Operators
|
|
40
|
+
|
|
41
|
+
| Operator | Example | Description |
|
|
42
|
+
|----------|---------|-------------|
|
|
43
|
+
| bare truthy | `dockOpen` | True if the value is truthy |
|
|
44
|
+
| `true` / `false` | `true` | Literal boolean values |
|
|
45
|
+
| `!` | `!paletteOpen` | Negation |
|
|
46
|
+
| `==` | `clientType == embedded` | Equality (string comparison) |
|
|
47
|
+
| `!=` | `clientType != standalone` | Inequality |
|
|
48
|
+
| `&&` | `dockOpen && !paletteOpen` | Logical AND |
|
|
49
|
+
| `\|\|` | `paletteOpen \|\| dockOpen` | Logical OR |
|
|
50
|
+
|
|
51
|
+
### Precedence
|
|
52
|
+
|
|
53
|
+
`||` (lowest) → `&&` → unary `!`
|
|
54
|
+
|
|
55
|
+
Each `||` branch is evaluated as a chain of `&&` parts: `a && b || c && d` = `(a AND b) OR (c AND d)`.
|
|
56
|
+
|
|
57
|
+
### Examples
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
// Always visible
|
|
61
|
+
when: 'true'
|
|
62
|
+
|
|
63
|
+
// Never visible (unconditionally hidden)
|
|
64
|
+
when: 'false'
|
|
65
|
+
|
|
66
|
+
// Only in embedded mode
|
|
67
|
+
when: 'clientType == embedded'
|
|
68
|
+
|
|
69
|
+
// Only when dock is open and palette is closed
|
|
70
|
+
when: 'dockOpen && !paletteOpen'
|
|
71
|
+
|
|
72
|
+
// When a specific dock is selected
|
|
73
|
+
when: 'dockSelectedId == my-plugin'
|
|
74
|
+
|
|
75
|
+
// Plugin-specific context
|
|
76
|
+
when: 'vite.mode == development'
|
|
77
|
+
|
|
78
|
+
// Compound: either in embedded with dock open, or in standalone
|
|
79
|
+
when: 'clientType == embedded && dockOpen || clientType == standalone'
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Built-in Context Variables
|
|
83
|
+
|
|
84
|
+
| Variable | Type | Description |
|
|
85
|
+
|----------|------|-------------|
|
|
86
|
+
| `clientType` | `'embedded' \| 'standalone'` | Current client mode |
|
|
87
|
+
| `dockOpen` | `boolean` | Whether the dock panel is currently open |
|
|
88
|
+
| `paletteOpen` | `boolean` | Whether the command palette is currently open |
|
|
89
|
+
| `dockSelectedId` | `string` | ID of the currently selected dock entry. Empty string (falsy) when none selected. |
|
|
90
|
+
|
|
91
|
+
## Namespaced Context Keys
|
|
92
|
+
|
|
93
|
+
Plugins can register context variables using namespaced keys with `.` or `:` separators:
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
// Flat key (recommended)
|
|
97
|
+
context['vite.mode'] = 'development'
|
|
98
|
+
context['vite:buildMode'] = 'lib'
|
|
99
|
+
|
|
100
|
+
// Nested object (also supported)
|
|
101
|
+
context.vite = { mode: 'development', ssr: true }
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Both styles work in `when` expressions:
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
when: 'vite.mode == development'
|
|
108
|
+
when: 'vite:buildMode == lib'
|
|
109
|
+
when: 'vite.ssr'
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Lookup Order
|
|
113
|
+
|
|
114
|
+
When resolving a namespaced key like `vite.mode`:
|
|
115
|
+
|
|
116
|
+
1. **Exact match** — looks for `ctx['vite.mode']` first
|
|
117
|
+
2. **Nested path** — falls back to `ctx.vite?.mode`
|
|
118
|
+
|
|
119
|
+
Flat keys take priority over nested objects if both exist. Use your plugin name as namespace prefix: `my-plugin.featureEnabled`, `rolldown:buildStep`.
|
|
120
|
+
|
|
121
|
+
## API Reference
|
|
122
|
+
|
|
123
|
+
```ts
|
|
124
|
+
import type { WhenContext } from '@vitejs/devtools-kit'
|
|
125
|
+
import { evaluateWhen, getContextValue } from '@vitejs/devtools-kit/utils/when'
|
|
126
|
+
|
|
127
|
+
const ctx: WhenContext = {
|
|
128
|
+
'clientType': 'embedded',
|
|
129
|
+
'dockOpen': true,
|
|
130
|
+
'paletteOpen': false,
|
|
131
|
+
'dockSelectedId': 'my-dock',
|
|
132
|
+
'vite.mode': 'development',
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
evaluateWhen('dockOpen && vite.mode == development', ctx) // true
|
|
136
|
+
evaluateWhen('clientType == standalone', ctx) // false
|
|
137
|
+
|
|
138
|
+
getContextValue('vite.mode', ctx) // 'development'
|
|
139
|
+
getContextValue('dockOpen', ctx) // true
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### `evaluateWhen(expression, ctx)`
|
|
143
|
+
|
|
144
|
+
Evaluates a when-clause expression string against a context object. Returns `boolean`.
|
|
145
|
+
|
|
146
|
+
### `getContextValue(key, ctx)`
|
|
147
|
+
|
|
148
|
+
Resolves a single context key (including namespaced keys) from the context object. Returns `unknown`.
|
|
149
|
+
|
|
150
|
+
### `WhenContext`
|
|
151
|
+
|
|
152
|
+
```ts
|
|
153
|
+
interface WhenContext {
|
|
154
|
+
clientType: 'embedded' | 'standalone'
|
|
155
|
+
dockOpen: boolean
|
|
156
|
+
paletteOpen: boolean
|
|
157
|
+
dockSelectedId: string
|
|
158
|
+
[key: string]: unknown // custom plugin variables
|
|
159
|
+
}
|
|
160
|
+
```
|
|
File without changes
|