@rozenite/vite-plugin 1.13.0 → 2.1.0
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/README.md +12 -0
- package/dist/bundle-dts.d.ts.map +1 -1
- package/dist/client-plugin.d.ts.map +1 -1
- package/dist/dev-host/assets/index-BgAxGQdD.js +13 -0
- package/dist/dev-host/assets/index-ClIYIppU.css +1 -0
- package/dist/dev-host/index.html +3 -3
- package/dist/dev-host/manifest.json +2 -2
- package/dist/index.cjs +34 -63
- package/dist/index.d.ts +9 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +34 -63
- package/dist/load-config.d.ts.map +1 -1
- package/dist/package-json.d.ts.map +1 -1
- package/dist/react-native-plugin.d.ts.map +1 -1
- package/dist/require-plugin.d.ts.map +1 -1
- package/dist/sdk-plugin.d.ts.map +1 -1
- package/dist/server-plugin.d.ts.map +1 -1
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/package.json +29 -30
- package/src/bundle-dts.ts +6 -14
- package/src/client-plugin.ts +13 -36
- package/src/dev-host/App.tsx +184 -414
- package/src/dev-host/components/DispatchForm.tsx +97 -121
- package/src/dev-host/components/FlowList.tsx +70 -102
- package/src/dev-host/components/MessageDetailsPane.tsx +50 -83
- package/src/dev-host/components/MessageLogPane.tsx +75 -66
- package/src/dev-host/components/PanelTabs.tsx +19 -10
- package/src/dev-host/constants.ts +0 -19
- package/src/dev-host/flow-runtime.ts +15 -12
- package/src/dev-host/index.html +1 -1
- package/src/dev-host/main.tsx +1 -10
- package/src/dev-host/styles.css +162 -830
- package/src/dev-host/types.ts +0 -9
- package/src/dev-host/utils.ts +1 -7
- package/src/dev-host/vite.config.mts +2 -0
- package/src/index.ts +16 -16
- package/src/load-config.ts +9 -20
- package/src/package-json.ts +1 -3
- package/src/react-native-plugin.ts +4 -2
- package/src/require-plugin.ts +6 -18
- package/src/sdk-plugin.ts +3 -0
- package/src/server-plugin.ts +3 -0
- package/src/utils.ts +1 -4
- package/dist/dev-host/assets/index-CkxvBMpp.css +0 -1
- package/dist/dev-host/assets/index-cNKHRwej.js +0 -11
- package/src/dev-host/components/MessagePayloadDetail.tsx +0 -32
- package/src/dev-host/components/ResizeHandle.tsx +0 -33
- package/src/dev-host/components/icons.tsx +0 -79
- package/src/dev-host/components/ui/Button.tsx +0 -91
- package/src/dev-host/components/ui/DropdownMenu.tsx +0 -84
- package/src/dev-host/components/ui/IconButton.tsx +0 -41
- package/src/dev-host/components/ui/Input.tsx +0 -73
- package/src/dev-host/components/ui/ScrollArea.tsx +0 -20
- package/src/dev-host/components/ui/Tabs.tsx +0 -166
- package/src/dev-host/components/ui/Textarea.tsx +0 -79
- package/src/dev-host/components/ui/ToggleGroup.tsx +0 -120
package/src/dev-host/types.ts
CHANGED
|
@@ -50,12 +50,3 @@ export type PluginMessage = {
|
|
|
50
50
|
type: string;
|
|
51
51
|
payload: unknown;
|
|
52
52
|
};
|
|
53
|
-
|
|
54
|
-
export type ResizeHandleId = 'devtools-height' | 'command-width' | 'details-width';
|
|
55
|
-
|
|
56
|
-
export type ResizeSession = {
|
|
57
|
-
handleId: ResizeHandleId;
|
|
58
|
-
pointerId: number;
|
|
59
|
-
element: HTMLElement;
|
|
60
|
-
onMove: (event: PointerEvent) => void;
|
|
61
|
-
};
|
package/src/dev-host/utils.ts
CHANGED
|
@@ -21,10 +21,6 @@ export const formatPayloadPreview = (payload: unknown) => {
|
|
|
21
21
|
}
|
|
22
22
|
};
|
|
23
23
|
|
|
24
|
-
export const isJsonTreeData = (value: unknown): value is Record<string, unknown> | unknown[] => {
|
|
25
|
-
return Array.isArray(value) || (typeof value === 'object' && value !== null);
|
|
26
|
-
};
|
|
27
|
-
|
|
28
24
|
export const formatMessageDate = (date: string) => {
|
|
29
25
|
return new Date(date).toLocaleString();
|
|
30
26
|
};
|
|
@@ -71,9 +67,7 @@ export const getInitialPanel = (panels: DevHostPanelEntry[]) => {
|
|
|
71
67
|
return panels[0] ?? null;
|
|
72
68
|
};
|
|
73
69
|
|
|
74
|
-
export const createMessageEntry = (
|
|
75
|
-
input: Omit<MessageEntry, 'id' | 'date'>,
|
|
76
|
-
): MessageEntry => {
|
|
70
|
+
export const createMessageEntry = (input: Omit<MessageEntry, 'id' | 'date'>): MessageEntry => {
|
|
77
71
|
return {
|
|
78
72
|
id: crypto.randomUUID(),
|
|
79
73
|
date: new Date().toISOString(),
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import tailwindcss from '@tailwindcss/vite';
|
|
3
4
|
import { defineConfig } from 'vite';
|
|
4
5
|
|
|
5
6
|
const HOST_APP_ROOT = fileURLToPath(new URL('./', import.meta.url));
|
|
@@ -9,6 +10,7 @@ export default defineConfig({
|
|
|
9
10
|
root: HOST_APP_ROOT,
|
|
10
11
|
base: './',
|
|
11
12
|
publicDir: false,
|
|
13
|
+
plugins: [tailwindcss()],
|
|
12
14
|
build: {
|
|
13
15
|
outDir: path.join(PACKAGE_ROOT, 'dist', 'dev-host'),
|
|
14
16
|
emptyOutDir: true,
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { PluginOption } from 'vite';
|
|
2
|
+
import tailwindcss from '@tailwindcss/vite';
|
|
2
3
|
import react from '@vitejs/plugin-react';
|
|
3
4
|
import reactNativeWeb from 'vite-plugin-react-native-web';
|
|
4
5
|
import path from 'node:path';
|
|
@@ -12,20 +13,12 @@ import { bundleTargetDeclarations } from './bundle-dts.js';
|
|
|
12
13
|
|
|
13
14
|
// vite-plugin-dts exports differently in CJS and ESM
|
|
14
15
|
const dtsPlugin =
|
|
15
|
-
'default' in maybeDtsPlugin
|
|
16
|
-
? (maybeDtsPlugin.default as typeof maybeDtsPlugin)
|
|
17
|
-
: maybeDtsPlugin;
|
|
16
|
+
'default' in maybeDtsPlugin ? (maybeDtsPlugin.default as typeof maybeDtsPlugin) : maybeDtsPlugin;
|
|
18
17
|
|
|
19
|
-
const getDtsPlugin = (
|
|
20
|
-
target: 'react-native' | 'metro' | 'sdk',
|
|
21
|
-
): PluginOption => {
|
|
18
|
+
const getDtsPlugin = (target: 'react-native' | 'metro' | 'sdk'): PluginOption => {
|
|
22
19
|
const projectRoot = process.cwd();
|
|
23
20
|
const entryRoot =
|
|
24
|
-
target === 'react-native'
|
|
25
|
-
? 'react-native.ts'
|
|
26
|
-
: target === 'metro'
|
|
27
|
-
? 'metro.ts'
|
|
28
|
-
: 'sdk.ts';
|
|
21
|
+
target === 'react-native' ? 'react-native.ts' : target === 'metro' ? 'metro.ts' : 'sdk.ts';
|
|
29
22
|
const distRoot = path.join(projectRoot, 'dist');
|
|
30
23
|
const targetRoot = path.join(distRoot, target);
|
|
31
24
|
const publicEntryPath = path.join(projectRoot, 'dist', target, 'index.d.ts');
|
|
@@ -57,10 +50,7 @@ const getDtsPlugin = (
|
|
|
57
50
|
};
|
|
58
51
|
}
|
|
59
52
|
|
|
60
|
-
if (
|
|
61
|
-
target === 'sdk' &&
|
|
62
|
-
filePath === rawSdkEntryPath
|
|
63
|
-
) {
|
|
53
|
+
if (target === 'sdk' && filePath === rawSdkEntryPath) {
|
|
64
54
|
return {
|
|
65
55
|
// vite-plugin-dts emits the SDK root declaration at dist/sdk.d.ts.
|
|
66
56
|
// Move it under dist/sdk/ before API Extractor rolls it up into the
|
|
@@ -87,7 +77,16 @@ const getDtsPlugin = (
|
|
|
87
77
|
});
|
|
88
78
|
};
|
|
89
79
|
|
|
90
|
-
export
|
|
80
|
+
export type RozenitePluginOptions = {
|
|
81
|
+
/**
|
|
82
|
+
* Configure Tailwind CSS v4 for client panels.
|
|
83
|
+
*
|
|
84
|
+
* @default true
|
|
85
|
+
*/
|
|
86
|
+
tailwind?: boolean;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
export const rozenitePlugin = ({ tailwind = true }: RozenitePluginOptions = {}): PluginOption[] => {
|
|
91
90
|
const isServer = process.env.VITE_ROZENITE_TARGET === 'server';
|
|
92
91
|
const isReactNative = process.env.VITE_ROZENITE_TARGET === 'react-native';
|
|
93
92
|
const isSdk = process.env.VITE_ROZENITE_TARGET === 'sdk';
|
|
@@ -106,6 +105,7 @@ export const rozenitePlugin = (): PluginOption[] => {
|
|
|
106
105
|
}
|
|
107
106
|
|
|
108
107
|
return [
|
|
108
|
+
...(tailwind ? [tailwindcss()] : []),
|
|
109
109
|
react(),
|
|
110
110
|
// @ts-expect-error: TypeScript gets confused by the dual export
|
|
111
111
|
reactNativeWeb(),
|
package/src/load-config.ts
CHANGED
|
@@ -66,9 +66,7 @@ export type RozeniteConfig = {
|
|
|
66
66
|
dev?: DevConfig;
|
|
67
67
|
};
|
|
68
68
|
|
|
69
|
-
export const loadConfig = async (
|
|
70
|
-
configPath: string
|
|
71
|
-
): Promise<RozeniteConfig> => {
|
|
69
|
+
export const loadConfig = async (configPath: string): Promise<RozeniteConfig> => {
|
|
72
70
|
const absoluteConfigPath = path.resolve(process.cwd(), configPath);
|
|
73
71
|
|
|
74
72
|
if (!fs.existsSync(absoluteConfigPath)) {
|
|
@@ -76,20 +74,13 @@ export const loadConfig = async (
|
|
|
76
74
|
}
|
|
77
75
|
|
|
78
76
|
try {
|
|
79
|
-
const configContent = await fs.promises.readFile(
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
absoluteConfigPath,
|
|
87
|
-
{
|
|
88
|
-
loader: 'ts',
|
|
89
|
-
format: 'cjs',
|
|
90
|
-
target: 'esnext',
|
|
91
|
-
}
|
|
92
|
-
);
|
|
77
|
+
const configContent = await fs.promises.readFile(absoluteConfigPath, 'utf-8');
|
|
78
|
+
|
|
79
|
+
const result = await transformWithEsbuild(configContent, absoluteConfigPath, {
|
|
80
|
+
loader: 'ts',
|
|
81
|
+
format: 'cjs',
|
|
82
|
+
target: 'esnext',
|
|
83
|
+
});
|
|
93
84
|
|
|
94
85
|
const moduleExports: { default?: unknown } = {};
|
|
95
86
|
const module = { exports: moduleExports };
|
|
@@ -108,9 +99,7 @@ export const loadConfig = async (
|
|
|
108
99
|
return config as RozeniteConfig;
|
|
109
100
|
} catch (error) {
|
|
110
101
|
if (error instanceof Error) {
|
|
111
|
-
throw new Error(
|
|
112
|
-
`Failed to load configuration from ${configPath}: ${error.message}`
|
|
113
|
-
);
|
|
102
|
+
throw new Error(`Failed to load configuration from ${configPath}: ${error.message}`);
|
|
114
103
|
}
|
|
115
104
|
throw new Error(`Failed to load configuration from ${configPath}`);
|
|
116
105
|
}
|
package/src/package-json.ts
CHANGED
|
@@ -7,9 +7,7 @@ export type PackageJSON = {
|
|
|
7
7
|
version: string;
|
|
8
8
|
};
|
|
9
9
|
|
|
10
|
-
export const getPackageJSON = async (
|
|
11
|
-
projectRoot: string
|
|
12
|
-
): Promise<PackageJSON> => {
|
|
10
|
+
export const getPackageJSON = async (projectRoot: string): Promise<PackageJSON> => {
|
|
13
11
|
const packageJSONPath = path.join(projectRoot, 'package.json');
|
|
14
12
|
const packageJSON = await fs.readFile(packageJSONPath, 'utf8');
|
|
15
13
|
return JSON.parse(packageJSON);
|
|
@@ -8,12 +8,14 @@ export const rozeniteReactNativePlugin = (): Plugin => {
|
|
|
8
8
|
const projectRoot = config.root ?? process.cwd();
|
|
9
9
|
|
|
10
10
|
config.build ??= {};
|
|
11
|
+
if (process.env.ROZENITE_BUILD === '1') {
|
|
12
|
+
config.build.emptyOutDir = false;
|
|
13
|
+
}
|
|
11
14
|
config.build.rollupOptions ??= {};
|
|
12
15
|
|
|
13
16
|
config.build.lib = {
|
|
14
17
|
entry: path.resolve(projectRoot, 'react-native.ts'),
|
|
15
|
-
fileName: (format) =>
|
|
16
|
-
`react-native/index.${format === 'es' ? 'js' : 'cjs'}`,
|
|
18
|
+
fileName: (format) => `react-native/index.${format === 'es' ? 'js' : 'cjs'}`,
|
|
17
19
|
};
|
|
18
20
|
|
|
19
21
|
config.build.rollupOptions.external = (id) => {
|
package/src/require-plugin.ts
CHANGED
|
@@ -86,9 +86,7 @@ const transformRequireToChunkReferences = (
|
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
const outFileName = getFileName(moduleInfo.referenceId);
|
|
89
|
-
const relPath = normalizePath(
|
|
90
|
-
path.posix.relative('react-native', outFileName),
|
|
91
|
-
);
|
|
89
|
+
const relPath = normalizePath(path.posix.relative('react-native', outFileName));
|
|
92
90
|
const requirePath = relPath.startsWith('.') ? relPath : `./${relPath}`;
|
|
93
91
|
|
|
94
92
|
return `require('${requirePath}')`;
|
|
@@ -143,10 +141,7 @@ export default function requirePlugin(): Plugin {
|
|
|
143
141
|
async buildStart(options) {
|
|
144
142
|
try {
|
|
145
143
|
assert(Array.isArray(options.input), 'input must be an array');
|
|
146
|
-
assert(
|
|
147
|
-
options.input.length === 1,
|
|
148
|
-
'input must be an array with one entry',
|
|
149
|
-
);
|
|
144
|
+
assert(options.input.length === 1, 'input must be an array with one entry');
|
|
150
145
|
|
|
151
146
|
input = options.input[0];
|
|
152
147
|
inputName = extractModuleName(input);
|
|
@@ -167,16 +162,11 @@ export default function requirePlugin(): Plugin {
|
|
|
167
162
|
|
|
168
163
|
this.addWatchFile(resolved.id);
|
|
169
164
|
|
|
170
|
-
const exportName = sanitizeChunkName(
|
|
171
|
-
extractModuleName(resolved.id),
|
|
172
|
-
);
|
|
165
|
+
const exportName = sanitizeChunkName(extractModuleName(resolved.id));
|
|
173
166
|
const wrapperName = `${exportName}${REQUIRE_WRAPPER_SUFFIX}`;
|
|
174
167
|
const virtualId = `${VIRTUAL_REQUIRE_PREFIX}${wrapperName}`;
|
|
175
168
|
|
|
176
|
-
virtualModuleSources.set(
|
|
177
|
-
virtualId,
|
|
178
|
-
`export * from ${JSON.stringify(req)};`,
|
|
179
|
-
);
|
|
169
|
+
virtualModuleSources.set(virtualId, `export * from ${JSON.stringify(req)};`);
|
|
180
170
|
|
|
181
171
|
const referenceId = this.emitFile({
|
|
182
172
|
type: 'chunk',
|
|
@@ -205,10 +195,8 @@ export default function requirePlugin(): Plugin {
|
|
|
205
195
|
}
|
|
206
196
|
|
|
207
197
|
return {
|
|
208
|
-
code: transformRequireToChunkReferences(
|
|
209
|
-
|
|
210
|
-
moduleInfoMap,
|
|
211
|
-
(referenceId) => normalizePath(this.getFileName(referenceId)),
|
|
198
|
+
code: transformRequireToChunkReferences(code, moduleInfoMap, (referenceId) =>
|
|
199
|
+
normalizePath(this.getFileName(referenceId)),
|
|
212
200
|
),
|
|
213
201
|
map: null,
|
|
214
202
|
};
|
package/src/sdk-plugin.ts
CHANGED
|
@@ -8,6 +8,9 @@ export const rozeniteSdkPlugin = (): Plugin => {
|
|
|
8
8
|
const projectRoot = config.root ?? process.cwd();
|
|
9
9
|
|
|
10
10
|
config.build ??= {};
|
|
11
|
+
if (process.env.ROZENITE_BUILD === '1') {
|
|
12
|
+
config.build.emptyOutDir = false;
|
|
13
|
+
}
|
|
11
14
|
config.build.lib = {
|
|
12
15
|
entry: path.resolve(projectRoot, 'sdk.ts'),
|
|
13
16
|
formats: ['es' as const, 'cjs' as const],
|
package/src/server-plugin.ts
CHANGED
|
@@ -10,6 +10,9 @@ export const rozeniteServerPlugin = (): Plugin => {
|
|
|
10
10
|
const projectRoot = config.root ?? process.cwd();
|
|
11
11
|
|
|
12
12
|
config.build ??= {};
|
|
13
|
+
if (process.env.ROZENITE_BUILD === '1') {
|
|
14
|
+
config.build.emptyOutDir = false;
|
|
15
|
+
}
|
|
13
16
|
config.build.lib = {
|
|
14
17
|
entry: path.resolve(projectRoot, 'metro.ts'),
|
|
15
18
|
formats: ['es' as const, 'cjs' as const],
|
package/src/utils.ts
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
|
|
4
|
-
export const resolveFileWithExtensions = (
|
|
5
|
-
directory: string,
|
|
6
|
-
baseName: string
|
|
7
|
-
): string | null => {
|
|
4
|
+
export const resolveFileWithExtensions = (directory: string, baseName: string): string | null => {
|
|
8
5
|
const extensions = ['.tsx', '.ts', '.jsx', '.js'];
|
|
9
6
|
|
|
10
7
|
for (const ext of extensions) {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
:root{color-scheme:dark;font-family:Switzer Variable,Inter,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;background:#000;color:#fff}*{box-sizing:border-box}html,body,#root{height:100%;margin:0}body{overflow:hidden;background:#000}button,input,textarea,select{font:inherit}.rz-shell{display:flex;height:100dvh;flex-direction:column;overflow:hidden;background:#000}.rz-topbar{display:flex;align-items:center;justify-content:space-between;gap:16px;min-height:52px;padding:10px 14px;border-bottom:1px solid rgba(255,255,255,.08);overflow:hidden;background:#0a0a0a}.rz-topbar-brand{display:inline-flex;align-items:center;flex:0 0 auto}.rz-topbar-brand svg{display:block;width:auto;height:20px}.rz-topbar-panel-picker{display:flex;align-items:center;min-width:0;justify-content:flex-end}.rz-workspace{flex:1;min-height:0;display:grid;grid-template-rows:minmax(0,1fr) 12px minmax(180px,var(--rz-devtools-height, 288px));overflow:hidden}.rz-card{min-height:0;overflow:hidden;border-top:1px solid rgba(255,255,255,.08)}.rz-card:first-child{border-top:0}.rz-iframe{display:block;width:100%;height:100%;border:0;background:#fff}.rz-iframe[data-resizing=true]{pointer-events:none}.rz-devtools{display:grid;min-height:0;grid-template-columns:minmax(0,1fr) var(--rz-command-splitter-width, 6px) minmax(260px,var(--rz-command-width, 320px))}.rz-devtools-mobile{display:flex;min-height:0;height:100%;width:100%;overflow:hidden}.rz-log-workspace{display:grid;min-height:0;position:relative;grid-template-columns:minmax(0,1fr) var(--rz-details-splitter-width, 0px) var(--rz-details-width, 0px)}.rz-resize-handle{position:relative;cursor:row-resize;background:#0a0a0a;-webkit-user-select:none;user-select:none;touch-action:none}.rz-resize-handle:before{content:"";position:absolute;top:50%;left:50%;width:72px;height:2px;border-radius:999px;background:#fff3;transform:translate(-50%,-50%)}.rz-resize-handle:after{content:"";position:absolute;inset:0;border-top:1px solid rgba(255,255,255,.08);border-bottom:1px solid rgba(255,255,255,.08)}.rz-resize-handle[data-dragging=true]:before,.rz-resize-handle:hover:before{background:#fff}.rz-column-resize-handle{position:relative;width:6px;min-width:6px;cursor:col-resize;background:#0a0a0a;-webkit-user-select:none;user-select:none;touch-action:none}.rz-column-resize-handle:before{content:"";position:absolute;top:50%;left:50%;width:2px;height:72px;border-radius:999px;background:#fff3;transform:translate(-50%,-50%)}.rz-column-resize-handle:after{content:"";position:absolute;inset:0;border-left:1px solid rgba(255,255,255,.08);border-right:1px solid rgba(255,255,255,.08)}.rz-column-resize-handle[data-dragging=true]:before,.rz-column-resize-handle:hover:before{background:#fff}.rz-column-resize-handle[data-dragging=true]:after,.rz-column-resize-handle:hover:after{border-left-color:#ffffff14;border-right-color:#ffffff14}.rz-pane{display:flex;flex-direction:column;min-height:0;overflow:hidden}.rz-pane+.rz-pane{border-left:1px solid rgba(255,255,255,.08)}.rz-pane[data-hidden=true],.rz-column-resize-handle[data-hidden=true]{display:none}.rz-devtools-mobile-tabs{display:grid;grid-template-rows:auto minmax(0,1fr);gap:8px;min-height:0;height:100%;width:100%;padding-top:8px}.rz-devtools-mobile-toggle{display:flex;align-items:flex-start;padding:0 8px}.rz-devtools-mobile-panel{display:flex;min-height:0;width:100%;overflow:hidden}.rz-devtools-mobile-panel>.rz-pane{flex:1;width:100%}.rz-tabs-root{width:100%;min-width:0}.rz-tabs-list{display:inline-flex;min-height:26px;max-width:100%;align-items:center;gap:2px;overflow:auto hidden;border:1px solid rgba(255,255,255,.08);border-radius:4px;background:#ffffff0a;padding:2px;scrollbar-width:none}.rz-tabs-list::-webkit-scrollbar{display:none}.rz-tabs-trigger{display:inline-flex;align-items:center;justify-content:center;white-space:nowrap;border:0;border-radius:2px;background:transparent;min-height:22px;padding:3px 9px;color:#fff9;font-size:12px;font-weight:500;line-height:1.2;letter-spacing:0;transition:background-color .12s ease,color .12s ease}.rz-tabs-trigger:hover{color:#fff}.rz-tabs-trigger[data-state=active]{background:#fff;color:#000}.rz-tabs-trigger:focus-visible,.rz-input:focus-visible,.rz-textarea:focus-visible,.rz-sidebar-close:focus-visible{outline:2px solid rgba(130,50,255,.95);outline-offset:-2px}.rz-scroll-area{position:relative;height:100%;width:100%;overflow:hidden}.rz-scroll-viewport{height:100%;width:100%;overflow-y:auto;overflow-x:hidden;scrollbar-width:thin;scrollbar-color:rgba(255,255,255,.18) transparent}.rz-scroll-viewport::-webkit-scrollbar{width:12px}.rz-scroll-viewport::-webkit-scrollbar-track{background:transparent}.rz-scroll-viewport::-webkit-scrollbar-thumb{border:3px solid transparent;border-radius:999px;background:#ffffff2e;background-clip:padding-box}.rz-message-list{min-width:100%;font-family:Geist Mono,ui-monospace,SFMono-Regular,Menlo,monospace}.rz-log-pane{display:grid;grid-template-rows:auto minmax(0,1fr);min-height:0;background:#050505}.rz-message-list-header,.rz-message-row{display:grid;grid-template-columns:40px 168px minmax(120px,180px) minmax(0,1fr);gap:0;align-items:center}.rz-message-list-header{position:sticky;top:0;z-index:1;background:#0a0a0a;color:#fff6;font-size:11px;line-height:16px;letter-spacing:.06em;text-transform:uppercase;border-bottom:1px solid rgba(255,255,255,.08)}.rz-message-header-cell,.rz-message-cell{min-width:0;padding:8px 12px}.rz-message-header-cell:first-child,.rz-message-cell:first-child{text-align:center}.rz-message-header-cell+.rz-message-header-cell,.rz-message-cell+.rz-message-cell{border-left:1px solid rgba(255,255,255,.04)}.rz-message-row{width:100%;border:0;background:transparent;color:inherit;text-align:left;padding:0;border-bottom:1px solid rgba(255,255,255,.06);cursor:pointer;transition:background-color .12s ease,box-shadow .12s ease}.rz-message-row:last-child{border-bottom:0}.rz-message-row:hover{background:#ffffff09}.rz-message-row[data-selected=true]{background:#3b82f624;box-shadow:inset 2px 0 #4da3ff}.rz-message-direction{display:flex;align-items:center;justify-content:center;color:#ffffffb3;font-size:12px;line-height:18px}.rz-message-arrow{display:inline-flex;width:16px;justify-content:center;font-size:14px;font-weight:700}.rz-message-dir-in .rz-message-arrow{color:#22c55e}.rz-message-dir-out .rz-message-arrow{color:#f59e0b}.rz-message-type{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#ffffffeb;font-size:12px;font-weight:500;line-height:18px}.rz-message-date{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#ffffff85;font-size:12px;line-height:18px}.rz-message-preview{margin:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#ffffff85;font-size:12px;line-height:18px}.rz-sidebar{display:grid;grid-template-rows:auto minmax(0,1fr);min-height:0;background:#050505;flex-grow:1}.rz-message-detail{display:flex;flex-direction:column;gap:16px;padding:16px;min-height:100%}.rz-sidebar-header{display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:53px;padding:12px 16px;border-bottom:1px solid rgba(255,255,255,.08);background:#ffffff05}.rz-sidebar-scroll{min-height:0}.rz-sidebar-scroll>.rz-scroll-viewport>*{min-height:100%}.rz-sidebar-title{color:#ffffffe0;font-size:12px;font-weight:600;line-height:18px;letter-spacing:.04em;text-transform:uppercase;font-family:Geist Mono,ui-monospace,SFMono-Regular,Menlo,monospace}.rz-header-actions{display:flex;align-items:center;gap:8px}.rz-sidebar-close{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border:0;border-radius:4px;background:transparent;color:#ffffff8f;cursor:pointer}.rz-sidebar-close:hover{background:#ffffff0f;color:#fff}.rz-sidebar-close:disabled{cursor:default;opacity:.4}.rz-sidebar-close:disabled:hover{background:transparent;color:#ffffff8f}.rz-sidebar-action-primary{background:#fff;color:#000}.rz-sidebar-action-primary:hover{background:#ffffffe0;color:#000}.rz-sidebar-action-primary:disabled:hover{background:#fff;color:#000}.rz-detail-section{display:grid;align-content:start;gap:8px;min-width:0}.rz-detail-value{min-width:0;border:1px solid rgba(255,255,255,.08);border-radius:4px;background:#ffffff08;padding:10px 12px;color:#ffffffe6;font-size:13px;line-height:1.5;letter-spacing:-.02em}.rz-detail-mono{font-family:Geist Mono,ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;line-height:1.5}.rz-detail-payload{display:flex;border:1px solid rgba(255,255,255,.08);border-radius:4px;background:#ffffff08;padding:12px}.rz-detail-pre{margin:0;white-space:pre-wrap;word-break:break-word}.rz-detail-json-tree{font-family:Geist Mono,ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;line-height:1.5}.rz-detail-json-tree ul,.rz-detail-json-tree li,.rz-detail-json-tree label,.rz-detail-json-tree span{font-size:inherit}.rz-command-form{display:flex;flex-direction:column;gap:12px;padding:16px;min-height:100%}.rz-action-tabs{min-height:100%}.rz-action-tabs-header{display:flex;align-items:center;justify-content:space-between;gap:12px}.rz-action-tab-panel{min-height:0}.rz-action-form{display:flex;flex-direction:column;gap:12px;min-height:100%}.rz-field{display:grid;gap:6px}.rz-template-list{display:flex;flex-wrap:wrap;gap:8px}.rz-preset-menu{position:relative}.rz-preset-icon-button{display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:1px solid rgba(255,255,255,.08);border-radius:6px;background:#ffffff0a;color:#ffffffe0;cursor:pointer;flex-shrink:0}.rz-preset-icon-button:hover{background:#ffffff14;color:#fff}.rz-baseui-preset-menu{min-width:220px;max-width:min(320px,calc(100vw - 24px))}.rz-template-button{border:1px solid rgba(255,255,255,.08);border-radius:999px;background:#ffffff0a;color:#ffffffdb;padding:6px 10px;font-size:12px;line-height:1.4;cursor:pointer}.rz-template-button:hover{background:#ffffff1a;color:#fff}.rz-template-button:focus-visible{outline:2px solid rgba(130,50,255,.95);outline-offset:1px}.rz-template-button:disabled{cursor:default;opacity:.4}.rz-template-button[data-active=true]{background:#8232ff2e;border-color:#8232ff80;color:#fff}.rz-flow-panel{display:grid;gap:16px}.rz-flow-list{display:grid;gap:8px}.rz-flow-list-button{display:flex;align-items:center;justify-content:space-between;gap:12px;width:100%;border:1px solid rgba(255,255,255,.08);border-radius:8px;background:#ffffff08;color:#ffffffe0;padding:10px 12px;text-align:left;cursor:pointer}.rz-flow-list-button:hover{background:#ffffff0f;color:#fff}.rz-flow-list-button:focus-visible{outline:2px solid rgba(130,50,255,.95);outline-offset:1px}.rz-flow-list-button:disabled{cursor:default;opacity:.4}.rz-flow-list-button[data-active=true]{background:#8232ff24;border-color:#8232ff73}.rz-flow-list-name{display:inline-flex;align-items:center;gap:6px;font-size:13px;line-height:1.4}.rz-flow-list-badge,.rz-flow-state-badge{display:inline-flex;align-items:center;justify-content:center;min-height:18px;padding:0 6px;border-radius:999px;background:#8232ff29;color:#c9a9ff;font-size:10px;line-height:1;font-family:Geist Mono,ui-monospace,SFMono-Regular,Menlo,monospace;text-transform:uppercase}.rz-flow-list-action{color:#ffffff8f;font-size:11px;line-height:1.4;font-family:Geist Mono,ui-monospace,SFMono-Regular,Menlo,monospace;text-transform:uppercase}.rz-flow-empty-state{border:1px dashed rgba(255,255,255,.12);border-radius:8px;padding:12px;color:#fff9;font-size:13px;line-height:1.5}.rz-flow-runs{display:grid;gap:12px}.rz-flow-state{display:grid;gap:8px;padding:12px;border:1px solid rgba(255,255,255,.08);border-radius:8px;background:#ffffff08}.rz-flow-state[data-status=running]{border-color:#8232ff73}.rz-flow-state[data-status=failed]{border-color:#ff787866}.rz-flow-state-header{display:flex;align-items:center;justify-content:space-between;gap:8px}.rz-flow-state-title{display:inline-flex;align-items:center;gap:6px;color:#ffffffe6;font-size:13px;line-height:1.4}.rz-flow-state-status{color:#fff9;font-size:12px;line-height:1.4;font-family:Geist Mono,ui-monospace,SFMono-Regular,Menlo,monospace;text-transform:uppercase}.rz-flow-state-error,.rz-flow-state-result{margin:0;border-radius:4px;background:#ffffff0a;padding:10px 12px;color:#ffffffd6;font-size:12px;line-height:1.5;white-space:pre-wrap;word-break:break-word}.rz-flow-state-error{color:#ffb4b4}.rz-flow-stop-button{flex-shrink:0}.rz-label{color:#fff9;font-size:12px;line-height:20px;letter-spacing:-.04em;font-family:Geist Mono,ui-monospace,SFMono-Regular,Menlo,monospace}.rz-input,.rz-textarea{width:100%;border:1px solid rgba(255,255,255,.08);border-radius:4px;background:#ffffff0a;color:#fff;padding:10px 12px;font-size:14px;line-height:1.5;letter-spacing:-.02em}.rz-textarea{min-height:112px;resize:none}.rz-button-row{display:flex;justify-content:flex-end;gap:8px;margin-top:auto}.rz-empty-state{display:flex;height:100%;align-items:center;justify-content:center;color:#ffffffb3;padding:24px;text-align:center;font-size:16px;line-height:1.5;letter-spacing:-.02em}@media(max-width:960px){.rz-topbar{padding-left:8px;padding-right:8px}.rz-topbar-brand svg{height:18px}.rz-topbar-panel-picker{overflow:hidden}.rz-workspace{grid-template-rows:minmax(0,1fr) 12px minmax(180px,var(--rz-devtools-height, 272px))}.rz-devtools-mobile-tabs{padding-top:8px}.rz-column-resize-handle{width:100%;min-width:0;min-height:6px;cursor:row-resize}.rz-column-resize-handle:before{width:72px;height:2px}.rz-column-resize-handle:after{border-left:0;border-right:0;border-top:1px solid rgba(255,255,255,.08);border-bottom:1px solid rgba(255,255,255,.08)}.rz-column-resize-handle[data-dragging=true]:after,.rz-column-resize-handle:hover:after{border-top-color:#ffffff14;border-bottom-color:#ffffff14}.rz-action-tabs-header{flex-wrap:wrap;align-items:flex-start}}@media(max-width:640px){.rz-message-list-header,.rz-message-row{grid-template-columns:36px 136px minmax(92px,136px) minmax(0,1fr)}.rz-message-header-cell,.rz-message-cell{padding:8px 10px}}
|