@oddsquad/vite-plugin-lit 0.6.0 → 0.7.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.
Files changed (83) hide show
  1. package/CHANGELOG.md +75 -0
  2. package/README.md +30 -12
  3. package/bin.mjs +107 -5
  4. package/dist/client/assets/{browser-agent-rpc-BXhoSh1z-DXAVFObe.js → browser-agent-rpc-BXhoSh1z-BuCvPGjS.js} +3 -3
  5. package/dist/client/assets/{browser-agent-rpc-BXhoSh1z-DXAVFObe.js.map → browser-agent-rpc-BXhoSh1z-BuCvPGjS.js.map} +1 -1
  6. package/dist/client/assets/{index-DVr5EnyB.js → index-D632jo79.js} +45 -19
  7. package/dist/client/assets/index-D632jo79.js.map +1 -0
  8. package/dist/client/index.html +1 -1
  9. package/dist/standalone/lit-devtools.js +6820 -0
  10. package/lib/confine.d.ts +22 -0
  11. package/lib/confine.d.ts.map +1 -0
  12. package/lib/confine.js +39 -0
  13. package/lib/confine.js.map +1 -0
  14. package/lib/devframe/allowed-origins.d.ts +13 -0
  15. package/lib/devframe/allowed-origins.d.ts.map +1 -0
  16. package/lib/devframe/allowed-origins.js +63 -0
  17. package/lib/devframe/allowed-origins.js.map +1 -0
  18. package/lib/devframe/definition.d.ts +10 -2
  19. package/lib/devframe/definition.d.ts.map +1 -1
  20. package/lib/devframe/definition.js +31 -9
  21. package/lib/devframe/definition.js.map +1 -1
  22. package/lib/devframe/protocol.d.ts +7 -3
  23. package/lib/devframe/protocol.d.ts.map +1 -1
  24. package/lib/devframe/protocol.js.map +1 -1
  25. package/lib/devframe/vite.d.ts.map +1 -1
  26. package/lib/devframe/vite.js +3 -0
  27. package/lib/devframe/vite.js.map +1 -1
  28. package/lib/http.d.ts +5 -0
  29. package/lib/http.d.ts.map +1 -1
  30. package/lib/http.js +5 -0
  31. package/lib/http.js.map +1 -1
  32. package/lib/options.d.ts +26 -0
  33. package/lib/options.d.ts.map +1 -1
  34. package/lib/options.js +19 -0
  35. package/lib/options.js.map +1 -1
  36. package/lib/plugin.d.ts.map +1 -1
  37. package/lib/plugin.js +3 -0
  38. package/lib/plugin.js.map +1 -1
  39. package/lib/plugins/open-in-editor.d.ts.map +1 -1
  40. package/lib/plugins/open-in-editor.js +11 -19
  41. package/lib/plugins/open-in-editor.js.map +1 -1
  42. package/lib/plugins/private-fields.d.ts +27 -0
  43. package/lib/plugins/private-fields.d.ts.map +1 -0
  44. package/lib/plugins/private-fields.js +259 -0
  45. package/lib/plugins/private-fields.js.map +1 -0
  46. package/lib/runtime/child-state.d.ts +100 -0
  47. package/lib/runtime/child-state.d.ts.map +1 -0
  48. package/lib/runtime/child-state.js +446 -0
  49. package/lib/runtime/child-state.js.map +1 -0
  50. package/lib/runtime/inspector/install.js +4 -1
  51. package/lib/runtime/inspector/install.js.map +1 -1
  52. package/lib/runtime/patch.d.ts +24 -0
  53. package/lib/runtime/patch.d.ts.map +1 -1
  54. package/lib/runtime/patch.js +22 -1
  55. package/lib/runtime/patch.js.map +1 -1
  56. package/lib/runtime/rpc-transport.d.ts +8 -0
  57. package/lib/runtime/rpc-transport.d.ts.map +1 -1
  58. package/lib/runtime/rpc-transport.js +1 -0
  59. package/lib/runtime/rpc-transport.js.map +1 -1
  60. package/lib/runtime/source-overlay/editors.d.ts.map +1 -1
  61. package/lib/runtime/source-overlay/editors.js +9 -4
  62. package/lib/runtime/source-overlay/editors.js.map +1 -1
  63. package/lib/runtime/standalone.d.ts +27 -0
  64. package/lib/runtime/standalone.d.ts.map +1 -0
  65. package/lib/runtime/standalone.js +50 -0
  66. package/lib/runtime/standalone.js.map +1 -0
  67. package/lib/runtime/timeline/install.js +4 -2
  68. package/lib/runtime/timeline/install.js.map +1 -1
  69. package/lib/runtime/timeline/lifecycle.d.ts.map +1 -1
  70. package/lib/runtime/timeline/lifecycle.js +5 -1
  71. package/lib/runtime/timeline/lifecycle.js.map +1 -1
  72. package/lib/snapshot.d.ts +2 -1
  73. package/lib/snapshot.d.ts.map +1 -1
  74. package/lib/snapshot.js +17 -1
  75. package/lib/snapshot.js.map +1 -1
  76. package/lib/source-meta.d.ts.map +1 -1
  77. package/lib/source-meta.js +40 -1
  78. package/lib/source-meta.js.map +1 -1
  79. package/package.json +18 -14
  80. package/types/timeline.d.ts +4 -1
  81. package/types/timeline.d.ts.map +1 -1
  82. package/types/timeline.js.map +1 -1
  83. package/dist/client/assets/index-DVr5EnyB.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -3,6 +3,81 @@
3
3
  Notable changes per release. Versions before 0.3.0 predate this file; see the
4
4
  git history for those.
5
5
 
6
+ ## 0.7.0 — 2026-09-29
7
+
8
+ Hot-patching covers two cases it used to get wrong: components with native
9
+ `#private` members, which threw, and child elements whose parent template you
10
+ edit, which lost their state. The standalone `lit-devtools dev` server also
11
+ gets pages to feed it: one script tag connects any page running Lit, whether
12
+ Vite serves it or not, directly or through a proxy. Two fixes ride along:
13
+ open-in-editor links lose a stray slash, and the timeline no longer misses the
14
+ first component's connect and disconnect.
15
+
16
+ ### Added
17
+
18
+ - **Components with `#private` fields keep hot-patching.** Editing an element
19
+ that uses native `#private` fields or methods now updates it in place and
20
+ keeps its private state, instead of throwing "Cannot read private member".
21
+ Set `hmr.privateFields: false` to keep real brand checks in dev.
22
+ - **Child components keep their state when you edit the parent.** Changing the
23
+ template a child element sits in no longer resets its `@state` and
24
+ `#private` fields; `hmr.childState: 'reuse'` keeps the original element
25
+ where it has no bindings, and `'reset'` restores the old behaviour. The
26
+ DevTools Settings tab can switch the mode live; the next edit uses it.
27
+ - **Pages outside Vite can feed the standalone panel.** `lit-devtools dev` now
28
+ prints a `<script src=".../lit-devtools.js">` tag; a page that loads it shows
29
+ its component tree, inspector and timeline in the panel, even when Vite
30
+ doesn't serve it or it's reached through a proxy or tunnel. Pages on
31
+ localhost connect on any port, and `--allow-origin` admits others, with `*`
32
+ for any subdomain (`--allow-origin 'https://*.webcontainer-api.io'` for
33
+ StackBlitz). HMR, source locations and open-in-editor still need Vite.
34
+
35
+ ### Fixed
36
+
37
+ - **Open-in-editor links use the documented URL form.** Links to VS Code,
38
+ Cursor, Zed and Windsurf no longer carry a double slash before absolute
39
+ paths like `/Users/...`.
40
+ - **The timeline records the first component's connect and disconnect.** On a
41
+ page with no Lit element when the DevTools runtime starts, the first
42
+ component defined afterwards now shows its `connectedCallback` and
43
+ `disconnectedCallback` events like the rest.
44
+
45
+ ## 0.6.1 — 2026-09-29
46
+
47
+ A fix release. Components whose `extends` clause holds braces load in dev
48
+ again, and the plugin now shares one devframe with the current Vite DevTools.
49
+ The rest comes from a security pass over the dev server: source opens and
50
+ snapshot exports stay inside the project, and the standalone server won't go
51
+ without its code gate on a network address.
52
+
53
+ ### Changed
54
+
55
+ - **`lit-devtools dev --no-auth` only runs on localhost.** Combined with a
56
+ `--host` other machines can reach, it now refuses to start instead of
57
+ letting anyone on the network drive the panel without a code.
58
+
59
+ ### Fixed
60
+
61
+ - **Components whose `extends` clause has braces load in dev again.** With
62
+ `sourceOverlay` on, a class like `extends Dialog<{open: boolean}>` or
63
+ `extends Mixin(Base, {shadow: true})` broke the module with a 500 from the
64
+ dev server. Broken since 0.3.0.
65
+ - **Exporting a snapshot can no longer delete your files.** The export wipes
66
+ its output directory before writing, and nothing checked which directory
67
+ that was. It now only writes inside the dev server's working directory and
68
+ only replaces an earlier snapshot.
69
+ - **The panel can only open source files inside your project.** Source links
70
+ from the DevTools panel used to open any absolute path they were given. They
71
+ now follow the same rule as the in-page overlay: the path has to be under
72
+ the Vite root or `server.fs.allow`.
73
+ - **Symlinks can't send the editor outside your project.** Opening a source
74
+ file used to follow a symlink under the project to wherever it pointed. Now
75
+ the target has to be inside the project too.
76
+ - **One copy of devframe alongside the current Vite DevTools.** The plugin
77
+ pinned devframe 1.0.0 exactly, so apps on `@vitejs/devtools-kit` 0.7.6
78
+ installed a second copy and got an unmet-peer warning. It now accepts any
79
+ devframe 1.x.
80
+
6
81
  ## 0.6.0 — 2026-09-29
7
82
 
8
83
  A small release with one feature. The Lit timeline can now appear in Chrome
package/README.md CHANGED
@@ -3,6 +3,8 @@
3
3
  A Vite plugin for Lit projects with true HMR, CSS delivery helpers for shadow
4
4
  roots, and a DevTools timeline.
5
5
 
6
+ https://github.com/user-attachments/assets/bacc7649-746a-4ecf-a017-0370b5af23ca
7
+
6
8
  **[Documentation →](https://oddcelot.github.io/vite-plugin-lit/)**
7
9
 
8
10
  Based on `@lit-labs/vite-plugin-lit` (formerly `@lit-labs/vite-hmr`) from the
@@ -119,21 +121,31 @@ The two differ in how the server is found, not in what it can do:
119
121
  plugin logs a warning saying so at startup, naming the reason.
120
122
 
121
123
  The CLI also has `lit-devtools dev`, a standalone devframe server. Started on
122
- its own it shows an empty panel, because it has no page of its own. A page
123
- served by a Vite dev server that loads this plugin's runtime can point itself
124
- at it and feed it the live component tree, inspector and timeline:
125
-
126
- ```ts
127
- import {connectToDevServer} from '@oddsquad/vite-plugin-lit/connect.js';
124
+ its own it shows an empty panel, because it has no page of its own. Add the
125
+ script tag it prints at startup to any page, including one that Vite does not
126
+ serve and one on another origin, and the page feeds it the live component tree,
127
+ inspector and timeline:
128
128
 
129
- await connectToDevServer('http://localhost:5180/');
129
+ ```html
130
+ <script src="http://localhost:5180/lit-devtools.js"></script>
130
131
  ```
131
132
 
132
- The server asks for its one-time code unless you start it with `--no-auth`. What
133
- this does not do yet: put the runtime into a page that is not on a Vite dev
134
- server, and set up the cross-origin access and authentication a page on another
135
- origin needs. The dev server's `__connection.json` sends no CORS headers today,
136
- so from a different origin the connection is blocked by the browser.
133
+ Put it before the scripts that define your components. The server asks for its
134
+ one-time code unless you start it with `--no-auth`: type the code into the
135
+ prompt the page shows, open the page once with `#devframe_otp=<code>` on its
136
+ URL, or skip the gate on a loopback host with `--no-auth`. Pages on a loopback
137
+ origin (any port) may connect; for any other origin, pass it to the server with
138
+ `--allow-origin https://myapp.test:8443` (repeatable). A `*` in the host
139
+ matches any subdomain, e.g. `--allow-origin 'https://*.webcontainer-api.io'`
140
+ for StackBlitz, where every port gets its own origin.
141
+
142
+ Outside Vite the page has no build-time transforms, so HMR patching, source
143
+ locations and open-in-editor do not work there; the tree, inspector and timeline
144
+ do. A page that Vite serves can instead call `connectToDevServer()` from
145
+ `@oddsquad/vite-plugin-lit/connect.js`.
146
+
147
+ To try it from this repo, run `pnpm run standalone:demo`; see
148
+ [Playground](#playground).
137
149
 
138
150
  ## Playground
139
151
 
@@ -146,6 +158,12 @@ straight from the repo URL. Run it locally from the repo root:
146
158
  pnpm dev # builds the plugin, then serves http://localhost:5179
147
159
  ```
148
160
 
161
+ The same playground runs in standalone mode, built to static files and fed to
162
+ a `lit-devtools dev` panel on another port: `pnpm run standalone:demo` here, or
163
+ [on StackBlitz](https://stackblitz.com/github/oddcelot/vite-plugin-lit/tree/main/playground?startScript=standalone)
164
+ with `?startScript=standalone`. StackBlitz installs the published plugin, so
165
+ that link works from the first release that ships standalone mode.
166
+
149
167
  ## Development
150
168
 
151
169
  Requires Node 26 and pnpm 12 (`corepack enable` picks up the pinned version).
package/bin.mjs CHANGED
@@ -30,7 +30,11 @@
30
30
  * @see plans/roadmap/03-cli-and-stdio-mcp.md
31
31
  */
32
32
 
33
+ import {readFile} from 'node:fs/promises';
34
+ import {createRequire} from 'node:module';
33
35
  import process from 'node:process';
36
+ import {pathToFileURL} from 'node:url';
37
+ import {resolveAllowedOrigins} from './lib/devframe/allowed-origins.js';
34
38
  import {createStandaloneLitDevframe} from './lib/devframe/rpc-source.js';
35
39
  import {PACKAGE_VERSION} from './lib/devframe/paths.js';
36
40
 
@@ -43,6 +47,19 @@ import {PACKAGE_VERSION} from './lib/devframe/paths.js';
43
47
  */
44
48
  const DEFAULT_DEV_PORT = 5180;
45
49
 
50
+ /** The script pages outside Vite load; built by `build:standalone`. */
51
+ const STANDALONE_SCRIPT = new URL(
52
+ './dist/standalone/lit-devtools.js',
53
+ import.meta.url
54
+ );
55
+
56
+ /** True for a host only this machine can reach. */
57
+ const isLoopbackHost = (host) =>
58
+ host === 'localhost' ||
59
+ host === '::1' ||
60
+ host === '[::1]' ||
61
+ /^127\.\d+\.\d+\.\d+$/.test(host);
62
+
46
63
  /** Fail with a readable message instead of a module-resolution stack trace. */
47
64
  const requirePeer = async (specifier, hint) => {
48
65
  try {
@@ -68,23 +85,108 @@ const main = async () => {
68
85
  .option('--port <port>', 'Port to listen on', {default: DEFAULT_DEV_PORT})
69
86
  .option('--host <host>', 'Host to bind to', {default: 'localhost'})
70
87
  .option('--open', 'Open the browser on start')
88
+ .option(
89
+ '--allow-origin <origin>',
90
+ 'Also let pages served from this origin connect, e.g. ' +
91
+ 'https://myapp.test:8443, or https://*.webcontainer-api.io for any ' +
92
+ 'host under a domain. Loopback origins on any port are always ' +
93
+ 'allowed. Repeatable.'
94
+ )
71
95
  .option(
72
96
  '--no-auth',
73
97
  'Skip the one-time-code gate, so a page can connect without a token'
74
98
  )
75
99
  .action(async (flags) => {
100
+ // Without the code gate, anything that can reach the port drives the
101
+ // panel's RPC: it can read the session and open project files in the
102
+ // developer's editor. On loopback that is this machine; on any other
103
+ // host it is the network.
104
+ if (flags.auth === false && !isLoopbackHost(String(flags.host))) {
105
+ console.error(
106
+ `[lit-devtools] --no-auth needs a loopback host, and ` +
107
+ `${flags.host} is reachable from other machines. Drop ` +
108
+ `--no-auth (pages then ask for the one-time code) or bind to ` +
109
+ `localhost.`
110
+ );
111
+ process.exit(1);
112
+ }
76
113
  const {createDevServer} = await import('devframe/adapters/dev');
77
114
  // A standalone server has no Vite, so it has no page of its own: the
78
- // panel stays empty until a page dials in with `connectToDevServer()`
79
- // (see `lib/runtime/rpc-transport.ts`), which carries the runtime's
80
- // usual channels over devframe RPC. Injecting the runtime into a page
81
- // that is not on a Vite dev server is not something this command does.
82
- await createDevServer(
115
+ // panel stays empty until a page dials in. It gets there by loading
116
+ // `/lit-devtools.js` (served below), which starts the runtime and calls
117
+ // `connectToDevServer()` (see `lib/runtime/rpc-transport.ts`). HMR
118
+ // patching and source metadata need Vite's transforms and are not part
119
+ // of it.
120
+ let allowedOrigins;
121
+ try {
122
+ allowedOrigins = resolveAllowedOrigins(
123
+ [flags.allowOrigin]
124
+ .flat()
125
+ .filter((origin) => origin != null)
126
+ .map(String)
127
+ );
128
+ } catch (error) {
129
+ console.error(`[lit-devtools] ${error.message}`);
130
+ process.exit(1);
131
+ }
132
+ let server;
133
+ const serveScript = async () => {
134
+ const headers = {
135
+ 'content-type': 'text/javascript; charset=utf-8',
136
+ 'cache-control': 'no-store',
137
+ };
138
+ let bundle;
139
+ try {
140
+ bundle = await readFile(STANDALONE_SCRIPT, 'utf8');
141
+ } catch {
142
+ return new Response(
143
+ '// lit-devtools: the standalone script is not built. ' +
144
+ 'Run `pnpm run build` in the package and restart.\n',
145
+ {status: 500, headers}
146
+ );
147
+ }
148
+ // The descriptor `__connection.json` would answer with, inlined so the
149
+ // page never fetches it: that request is cross-origin from a page
150
+ // that is not on this server, and gets no CORS headers. Picked, not
151
+ // spread, so nothing else devframe puts in it rides along to any page
152
+ // that can load a script tag.
153
+ const {backend, websocket, sse} = server.connectionMeta();
154
+ const config = {
155
+ url: server.origin + '/',
156
+ connectionMeta: {backend, websocket, sse},
157
+ };
158
+ return new Response(
159
+ `globalThis.__LIT_DEVTOOLS_CONNECT__ = ${JSON.stringify(config)};\n${bundle}`,
160
+ {headers}
161
+ );
162
+ };
163
+ // devframe mounts a static catch-all that answers 404 for paths it
164
+ // does not know, so a route added to its app in `onReady` would never be
165
+ // reached. The route has to go on the app *before* devframe's, which
166
+ // means handing it one -- built from the copy of h3 devframe itself
167
+ // resolves, so the two agree on the class.
168
+ const devframeRequire = createRequire(
169
+ import.meta.resolve('devframe/adapters/dev')
170
+ );
171
+ const {H3} = await import(
172
+ pathToFileURL(devframeRequire.resolve('h3')).href
173
+ );
174
+ const app = new H3();
175
+ app.use('/lit-devtools.js', serveScript);
176
+ server = await createDevServer(
83
177
  createStandaloneLitDevframe({version: PACKAGE_VERSION}),
84
178
  {
85
179
  host: flags.host,
86
180
  port: Number(flags.port),
87
181
  flags: {open: Boolean(flags.open), auth: flags.auth},
182
+ app,
183
+ ...(allowedOrigins !== undefined ? {allowedOrigins} : {}),
184
+ onReady({origin}) {
185
+ console.log(
186
+ `\n[lit-devtools] Add this to a page to connect it:\n\n` +
187
+ ` <script src="${origin}/lit-devtools.js"></script>\n`
188
+ );
189
+ },
88
190
  }
89
191
  );
90
192
  });
@@ -1,5 +1,5 @@
1
- import { n as onBrowserAgentToolsChanged, r as nanoid, t as listBrowserAgentTools } from "./index-DVr5EnyB.js";
2
- //#region node_modules/.pnpm/devframe@1.0.0_@devframes+agentic@1.0.0_cac@7.0.0_srvx@1.0.5/node_modules/devframe/dist/browser-agent-rpc-BXhoSh1z.mjs
1
+ import { n as onBrowserAgentToolsChanged, r as nanoid, t as listBrowserAgentTools } from "./index-D632jo79.js";
2
+ //#region node_modules/.pnpm/devframe@1.1.0_@devframes+agentic@1.1.0_cac@7.0.0_srvx@1.0.5/node_modules/devframe/dist/browser-agent-rpc-BXhoSh1z.mjs
3
3
  var CLIENT_ID_STORAGE_KEY = "devframe:client-id";
4
4
  var memoryClientId;
5
5
  /**
@@ -66,4 +66,4 @@ function setupBrowserAgentRpcBridge(rpc) {
66
66
  //#endregion
67
67
  export { setupBrowserAgentRpcBridge };
68
68
 
69
- //# sourceMappingURL=browser-agent-rpc-BXhoSh1z-DXAVFObe.js.map
69
+ //# sourceMappingURL=browser-agent-rpc-BXhoSh1z-BuCvPGjS.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"browser-agent-rpc-BXhoSh1z-DXAVFObe.js","names":[],"sources":["../../../node_modules/.pnpm/devframe@1.0.0_@devframes+agentic@1.0.0_cac@7.0.0_srvx@1.0.5/node_modules/devframe/dist/browser-agent-rpc-BXhoSh1z.mjs"],"sourcesContent":["import { nanoid } from \"./utils/nanoid.mjs\";\nimport { n as onBrowserAgentToolsChanged, t as listBrowserAgentTools } from \"./browser-agent-Pu-FLk6I.mjs\";\n//#region src/client/client-id.ts\nconst CLIENT_ID_STORAGE_KEY = \"devframe:client-id\";\nlet memoryClientId;\n/**\n* This browser tab's stable client id: one nanoid per tab, persisted in\n* `sessionStorage` so it survives page reloads and RPC reconnects. The node\n* side uses it to tell connected tabs apart across reconnects (see #394).\n*\n* Tab duplication copies `sessionStorage`, so two tabs can briefly share an id\n* until per-tab disambiguation lands with the wider tab-metadata work.\n*/\nfunction resolveClientId(win = globalThis.window) {\n\ttry {\n\t\tconst storage = win?.sessionStorage;\n\t\tif (storage) {\n\t\t\tlet id = storage.getItem(CLIENT_ID_STORAGE_KEY);\n\t\t\tif (!id) {\n\t\t\t\tid = nanoid();\n\t\t\t\tstorage.setItem(CLIENT_ID_STORAGE_KEY, id);\n\t\t\t}\n\t\t\treturn id;\n\t\t}\n\t} catch {}\n\tmemoryClientId ??= nanoid();\n\treturn memoryClientId;\n}\n//#endregion\n//#region src/client/browser-agent-rpc.ts\n/** Mirror this document's browser-agent registry over its existing RPC connection. */\nfunction setupBrowserAgentRpcBridge(rpc) {\n\trpc.client.register({\n\t\tname: \"devframe:agent:invoke-client-tool\",\n\t\ttype: \"action\",\n\t\tjsonSerializable: true,\n\t\thandler: async (id, args) => {\n\t\t\tconst tool = listBrowserAgentTools().find((tool) => tool.id === id);\n\t\t\tif (!tool) throw new Error(`[devframe/agent] browser tool \"${id}\" not found`);\n\t\t\treturn await tool.invoke(args);\n\t\t}\n\t});\n\tlet queued = false;\n\tlet disposed = false;\n\tlet lastSyncedCount = 0;\n\tconst sync = () => {\n\t\tif (queued || disposed) return;\n\t\tqueued = true;\n\t\tqueueMicrotask(async () => {\n\t\t\tqueued = false;\n\t\t\tif (disposed) return;\n\t\t\tconst manifests = listBrowserAgentTools().map(({ invoke: _, ...manifest }) => manifest);\n\t\t\tif (manifests.length === 0 && lastSyncedCount === 0) return;\n\t\t\tlastSyncedCount = manifests.length;\n\t\t\tawait rpc.callOptional(\"devframe:agent:sync-client-tools\", resolveClientId(), manifests).catch(() => {});\n\t\t});\n\t};\n\tconst stopTools = onBrowserAgentToolsChanged(sync);\n\tconst stopConnection = rpc.events.on(\"connection:status\", (status) => {\n\t\tif (status === \"connected\") sync();\n\t});\n\tsync();\n\treturn () => {\n\t\tdisposed = true;\n\t\tstopTools();\n\t\tstopConnection();\n\t};\n}\n//#endregion\nexport { setupBrowserAgentRpcBridge };\n"],"x_google_ignoreList":[0],"mappings":";;AAGA,IAAM,wBAAwB;AAC9B,IAAI;;;;;;;;;AASJ,SAAS,gBAAgB,MAAM,WAAW,QAAQ;CACjD,IAAI;EACH,MAAM,UAAU,KAAK;EACrB,IAAI,SAAS;GACZ,IAAI,KAAK,QAAQ,QAAQ,qBAAqB;GAC9C,IAAI,CAAC,IAAI;IACR,KAAK,OAAO;IACZ,QAAQ,QAAQ,uBAAuB,EAAE;GAC1C;GACA,OAAO;EACR;CACD,QAAQ,CAAC;CACT,mBAAmB,OAAO;CAC1B,OAAO;AACR;;AAIA,SAAS,2BAA2B,KAAK;CACxC,IAAI,OAAO,SAAS;EACnB,MAAM;EACN,MAAM;EACN,kBAAkB;EAClB,SAAS,OAAO,IAAI,SAAS;GAC5B,MAAM,OAAO,sBAAsB,CAAC,CAAC,MAAM,SAAS,KAAK,OAAO,EAAE;GAClE,IAAI,CAAC,MAAM,MAAM,IAAI,MAAM,kCAAkC,GAAG,YAAY;GAC5E,OAAO,MAAM,KAAK,OAAO,IAAI;EAC9B;CACD,CAAC;CACD,IAAI,SAAS;CACb,IAAI,WAAW;CACf,IAAI,kBAAkB;CACtB,MAAM,aAAa;EAClB,IAAI,UAAU,UAAU;EACxB,SAAS;EACT,eAAe,YAAY;GAC1B,SAAS;GACT,IAAI,UAAU;GACd,MAAM,YAAY,sBAAsB,CAAC,CAAC,KAAK,EAAE,QAAQ,GAAG,GAAG,eAAe,QAAQ;GACtF,IAAI,UAAU,WAAW,KAAK,oBAAoB,GAAG;GACrD,kBAAkB,UAAU;GAC5B,MAAM,IAAI,aAAa,oCAAoC,gBAAgB,GAAG,SAAS,CAAC,CAAC,YAAY,CAAC,CAAC;EACxG,CAAC;CACF;CACA,MAAM,YAAY,2BAA2B,IAAI;CACjD,MAAM,iBAAiB,IAAI,OAAO,GAAG,sBAAsB,WAAW;EACrE,IAAI,WAAW,aAAa,KAAK;CAClC,CAAC;CACD,KAAK;CACL,aAAa;EACZ,WAAW;EACX,UAAU;EACV,eAAe;CAChB;AACD"}
1
+ {"version":3,"file":"browser-agent-rpc-BXhoSh1z-BuCvPGjS.js","names":[],"sources":["../../../node_modules/.pnpm/devframe@1.1.0_@devframes+agentic@1.1.0_cac@7.0.0_srvx@1.0.5/node_modules/devframe/dist/browser-agent-rpc-BXhoSh1z.mjs"],"sourcesContent":["import { nanoid } from \"./utils/nanoid.mjs\";\nimport { n as onBrowserAgentToolsChanged, t as listBrowserAgentTools } from \"./browser-agent-Pu-FLk6I.mjs\";\n//#region src/client/client-id.ts\nconst CLIENT_ID_STORAGE_KEY = \"devframe:client-id\";\nlet memoryClientId;\n/**\n* This browser tab's stable client id: one nanoid per tab, persisted in\n* `sessionStorage` so it survives page reloads and RPC reconnects. The node\n* side uses it to tell connected tabs apart across reconnects (see #394).\n*\n* Tab duplication copies `sessionStorage`, so two tabs can briefly share an id\n* until per-tab disambiguation lands with the wider tab-metadata work.\n*/\nfunction resolveClientId(win = globalThis.window) {\n\ttry {\n\t\tconst storage = win?.sessionStorage;\n\t\tif (storage) {\n\t\t\tlet id = storage.getItem(CLIENT_ID_STORAGE_KEY);\n\t\t\tif (!id) {\n\t\t\t\tid = nanoid();\n\t\t\t\tstorage.setItem(CLIENT_ID_STORAGE_KEY, id);\n\t\t\t}\n\t\t\treturn id;\n\t\t}\n\t} catch {}\n\tmemoryClientId ??= nanoid();\n\treturn memoryClientId;\n}\n//#endregion\n//#region src/client/browser-agent-rpc.ts\n/** Mirror this document's browser-agent registry over its existing RPC connection. */\nfunction setupBrowserAgentRpcBridge(rpc) {\n\trpc.client.register({\n\t\tname: \"devframe:agent:invoke-client-tool\",\n\t\ttype: \"action\",\n\t\tjsonSerializable: true,\n\t\thandler: async (id, args) => {\n\t\t\tconst tool = listBrowserAgentTools().find((tool) => tool.id === id);\n\t\t\tif (!tool) throw new Error(`[devframe/agent] browser tool \"${id}\" not found`);\n\t\t\treturn await tool.invoke(args);\n\t\t}\n\t});\n\tlet queued = false;\n\tlet disposed = false;\n\tlet lastSyncedCount = 0;\n\tconst sync = () => {\n\t\tif (queued || disposed) return;\n\t\tqueued = true;\n\t\tqueueMicrotask(async () => {\n\t\t\tqueued = false;\n\t\t\tif (disposed) return;\n\t\t\tconst manifests = listBrowserAgentTools().map(({ invoke: _, ...manifest }) => manifest);\n\t\t\tif (manifests.length === 0 && lastSyncedCount === 0) return;\n\t\t\tlastSyncedCount = manifests.length;\n\t\t\tawait rpc.callOptional(\"devframe:agent:sync-client-tools\", resolveClientId(), manifests).catch(() => {});\n\t\t});\n\t};\n\tconst stopTools = onBrowserAgentToolsChanged(sync);\n\tconst stopConnection = rpc.events.on(\"connection:status\", (status) => {\n\t\tif (status === \"connected\") sync();\n\t});\n\tsync();\n\treturn () => {\n\t\tdisposed = true;\n\t\tstopTools();\n\t\tstopConnection();\n\t};\n}\n//#endregion\nexport { setupBrowserAgentRpcBridge };\n"],"x_google_ignoreList":[0],"mappings":";;AAGA,IAAM,wBAAwB;AAC9B,IAAI;;;;;;;;;AASJ,SAAS,gBAAgB,MAAM,WAAW,QAAQ;CACjD,IAAI;EACH,MAAM,UAAU,KAAK;EACrB,IAAI,SAAS;GACZ,IAAI,KAAK,QAAQ,QAAQ,qBAAqB;GAC9C,IAAI,CAAC,IAAI;IACR,KAAK,OAAO;IACZ,QAAQ,QAAQ,uBAAuB,EAAE;GAC1C;GACA,OAAO;EACR;CACD,QAAQ,CAAC;CACT,mBAAmB,OAAO;CAC1B,OAAO;AACR;;AAIA,SAAS,2BAA2B,KAAK;CACxC,IAAI,OAAO,SAAS;EACnB,MAAM;EACN,MAAM;EACN,kBAAkB;EAClB,SAAS,OAAO,IAAI,SAAS;GAC5B,MAAM,OAAO,sBAAsB,CAAC,CAAC,MAAM,SAAS,KAAK,OAAO,EAAE;GAClE,IAAI,CAAC,MAAM,MAAM,IAAI,MAAM,kCAAkC,GAAG,YAAY;GAC5E,OAAO,MAAM,KAAK,OAAO,IAAI;EAC9B;CACD,CAAC;CACD,IAAI,SAAS;CACb,IAAI,WAAW;CACf,IAAI,kBAAkB;CACtB,MAAM,aAAa;EAClB,IAAI,UAAU,UAAU;EACxB,SAAS;EACT,eAAe,YAAY;GAC1B,SAAS;GACT,IAAI,UAAU;GACd,MAAM,YAAY,sBAAsB,CAAC,CAAC,KAAK,EAAE,QAAQ,GAAG,GAAG,eAAe,QAAQ;GACtF,IAAI,UAAU,WAAW,KAAK,oBAAoB,GAAG;GACrD,kBAAkB,UAAU;GAC5B,MAAM,IAAI,aAAa,oCAAoC,gBAAgB,GAAG,SAAS,CAAC,CAAC,YAAY,CAAC,CAAC;EACxG,CAAC;CACF;CACA,MAAM,YAAY,2BAA2B,IAAI;CACjD,MAAM,iBAAiB,IAAI,OAAO,GAAG,sBAAsB,WAAW;EACrE,IAAI,WAAW,aAAa,KAAK;CAClC,CAAC;CACD,KAAK;CACL,aAAa;EACZ,WAAW;EACX,UAAU;EACV,eAAe;CAChB;AACD"}
@@ -1457,7 +1457,7 @@ var listElements = (events) => {
1457
1457
  }));
1458
1458
  };
1459
1459
  //#endregion
1460
- //#region \0@oxc-project+runtime@0.149.0/helpers/esm/decorate.js
1460
+ //#region \0@oxc-project+runtime@0.151.0/helpers/esm/decorate.js
1461
1461
  function __decorate(decorators, target, key, desc) {
1462
1462
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1463
1463
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -2656,7 +2656,7 @@ var VirtualizeDirective = class extends f {
2656
2656
  };
2657
2657
  var virtualize = e$1(VirtualizeDirective);
2658
2658
  //#endregion
2659
- //#region node_modules/.pnpm/devframe@1.0.0_@devframes+agentic@1.0.0_cac@7.0.0_srvx@1.0.5/node_modules/devframe/dist/utils/colors.mjs
2659
+ //#region node_modules/.pnpm/devframe@1.1.0_@devframes+agentic@1.1.0_cac@7.0.0_srvx@1.0.5/node_modules/devframe/dist/utils/colors.mjs
2660
2660
  function makeColor(open, close) {
2661
2661
  const o = `\x1B[${open}m`;
2662
2662
  const c = `\x1B[${close}m`;
@@ -2686,7 +2686,7 @@ var colors = {
2686
2686
  underline: makeColor(4, 24)
2687
2687
  };
2688
2688
  //#endregion
2689
- //#region node_modules/.pnpm/nostics@1.2.0/node_modules/nostics/dist/index.mjs
2689
+ //#region node_modules/.pnpm/nostics@1.3.0/node_modules/nostics/dist/index.mjs
2690
2690
  /**
2691
2691
  * Transforms a value or a function that returns a value to a value.
2692
2692
  *
@@ -2723,6 +2723,10 @@ var Diagnostic = class Diagnostic extends Error {
2723
2723
  */
2724
2724
  sources;
2725
2725
  /**
2726
+ * Structured information associated with this diagnostic code.
2727
+ */
2728
+ data;
2729
+ /**
2726
2730
  * Alias for {@link Error.message}: the reason this diagnostic was raised.
2727
2731
  */
2728
2732
  get why() {
@@ -2741,6 +2745,7 @@ var Diagnostic = class Diagnostic extends Error {
2741
2745
  this.fix = init.fix;
2742
2746
  this.docs = init.docs;
2743
2747
  this.sources = init.sources;
2748
+ this.data = init.data;
2744
2749
  captureStackTrace?.(this, captureFrom);
2745
2750
  }
2746
2751
  /**
@@ -2754,6 +2759,7 @@ var Diagnostic = class Diagnostic extends Error {
2754
2759
  docs: this.docs,
2755
2760
  sources: this.sources,
2756
2761
  cause: this.cause,
2762
+ data: this.data,
2757
2763
  stack: this.stack
2758
2764
  };
2759
2765
  }
@@ -2789,7 +2795,8 @@ function defineDiagnostics(options) {
2789
2795
  fix: toValueWithArgs(def.fix, params),
2790
2796
  docs,
2791
2797
  cause: params.cause,
2792
- sources: params.sources
2798
+ sources: params.sources,
2799
+ data: toValueWithArgs(def.data, params)
2793
2800
  }, handle);
2794
2801
  for (const reporter of reporters) reporter(diagnostic, reporterOptions);
2795
2802
  return diagnostic;
@@ -2799,7 +2806,7 @@ function defineDiagnostics(options) {
2799
2806
  return result;
2800
2807
  }
2801
2808
  //#endregion
2802
- //#region node_modules/.pnpm/nostics@1.2.0/node_modules/nostics/dist/formatters/ansi.mjs
2809
+ //#region node_modules/.pnpm/nostics@1.3.0/node_modules/nostics/dist/formatters/ansi.mjs
2803
2810
  /* @__NO_SIDE_EFFECTS__ */
2804
2811
  function ansiFormatter(colors) {
2805
2812
  return (d) => {
@@ -2815,7 +2822,7 @@ function ansiFormatter(colors) {
2815
2822
  };
2816
2823
  }
2817
2824
  //#endregion
2818
- //#region node_modules/.pnpm/devframe@1.0.0_@devframes+agentic@1.0.0_cac@7.0.0_srvx@1.0.5/node_modules/devframe/dist/tool-input-BAQXvvqL.mjs
2825
+ //#region node_modules/.pnpm/devframe@1.1.0_@devframes+agentic@1.1.0_cac@7.0.0_srvx@1.0.5/node_modules/devframe/dist/tool-input-BAQXvvqL.mjs
2819
2826
  /**
2820
2827
  * Centralized registry of the core devframe event names: the node-side host
2821
2828
  * bus events, the client RPC connection events, and the server→client
@@ -3194,7 +3201,7 @@ function toolInputToRpcArgs(input, argumentCount) {
3194
3201
  return collectPositionalArgs(input, argumentCount) ?? [input];
3195
3202
  }
3196
3203
  //#endregion
3197
- //#region node_modules/.pnpm/devframe@1.0.0_@devframes+agentic@1.0.0_cac@7.0.0_srvx@1.0.5/node_modules/devframe/dist/hash-DdPnc4k3.mjs
3204
+ //#region node_modules/.pnpm/devframe@1.1.0_@devframes+agentic@1.1.0_cac@7.0.0_srvx@1.0.5/node_modules/devframe/dist/hash-DdPnc4k3.mjs
3198
3205
  function serialize$1(input) {
3199
3206
  if (typeof input === "string") return `'${input}'`;
3200
3207
  return new Serializer().serialize(input);
@@ -3547,7 +3554,7 @@ function hash(value) {
3547
3554
  return hash$1(value);
3548
3555
  }
3549
3556
  //#endregion
3550
- //#region node_modules/.pnpm/devframe@1.0.0_@devframes+agentic@1.0.0_cac@7.0.0_srvx@1.0.5/node_modules/devframe/dist/utils/events.mjs
3557
+ //#region node_modules/.pnpm/devframe@1.1.0_@devframes+agentic@1.1.0_cac@7.0.0_srvx@1.0.5/node_modules/devframe/dist/utils/events.mjs
3551
3558
  /**
3552
3559
  * Create event emitter.
3553
3560
  */
@@ -3586,7 +3593,7 @@ function createEventEmitter() {
3586
3593
  };
3587
3594
  }
3588
3595
  //#endregion
3589
- //#region node_modules/.pnpm/devframe@1.0.0_@devframes+agentic@1.0.0_cac@7.0.0_srvx@1.0.5/node_modules/devframe/dist/utils/url.mjs
3596
+ //#region node_modules/.pnpm/devframe@1.1.0_@devframes+agentic@1.1.0_cac@7.0.0_srvx@1.0.5/node_modules/devframe/dist/utils/url.mjs
3590
3597
  /**
3591
3598
  * URL path-joining and slash-normalization helpers shared by the adapters,
3592
3599
  * the RPC clients, and the hub's mount-path plumbing. In-house replacements
@@ -3631,7 +3638,7 @@ function withProtocol(input, protocol) {
3631
3638
  return protocol + (match ? input.slice(match[0].length) : input);
3632
3639
  }
3633
3640
  //#endregion
3634
- //#region node_modules/.pnpm/devframe@1.0.0_@devframes+agentic@1.0.0_cac@7.0.0_srvx@1.0.5/node_modules/devframe/dist/utils/nanoid.mjs
3641
+ //#region node_modules/.pnpm/devframe@1.1.0_@devframes+agentic@1.1.0_cac@7.0.0_srvx@1.0.5/node_modules/devframe/dist/utils/nanoid.mjs
3635
3642
  var urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
3636
3643
  function nanoid(size = 21) {
3637
3644
  let id = "";
@@ -3640,7 +3647,7 @@ function nanoid(size = 21) {
3640
3647
  return id;
3641
3648
  }
3642
3649
  //#endregion
3643
- //#region node_modules/.pnpm/devframe@1.0.0_@devframes+agentic@1.0.0_cac@7.0.0_srvx@1.0.5/node_modules/devframe/dist/shared-state-eQVYHNqA.mjs
3650
+ //#region node_modules/.pnpm/devframe@1.1.0_@devframes+agentic@1.1.0_cac@7.0.0_srvx@1.0.5/node_modules/devframe/dist/shared-state-eQVYHNqA.mjs
3644
3651
  var NOTHING = Symbol.for("immer-nothing");
3645
3652
  var DRAFTABLE = Symbol.for("immer-draftable");
3646
3653
  var DRAFT_STATE = Symbol.for("immer-state");
@@ -4584,7 +4591,7 @@ function createSharedState(options) {
4584
4591
  };
4585
4592
  }
4586
4593
  //#endregion
4587
- //#region node_modules/.pnpm/devframe@1.0.0_@devframes+agentic@1.0.0_cac@7.0.0_srvx@1.0.5/node_modules/devframe/dist/structured-clone-CgtQ61SA.mjs
4594
+ //#region node_modules/.pnpm/devframe@1.1.0_@devframes+agentic@1.1.0_cac@7.0.0_srvx@1.0.5/node_modules/devframe/dist/structured-clone-CgtQ61SA.mjs
4588
4595
  var env = typeof self === "object" ? self : globalThis;
4589
4596
  var SAFE_ERROR_NAMES = /* @__PURE__ */ new Set([
4590
4597
  "Error",
@@ -4824,7 +4831,7 @@ function structuredCloneParse(value) {
4824
4831
  return parse(value);
4825
4832
  }
4826
4833
  //#endregion
4827
- //#region node_modules/.pnpm/devframe@1.0.0_@devframes+agentic@1.0.0_cac@7.0.0_srvx@1.0.5/node_modules/devframe/dist/utils/streaming-channel.mjs
4834
+ //#region node_modules/.pnpm/devframe@1.1.0_@devframes+agentic@1.1.0_cac@7.0.0_srvx@1.0.5/node_modules/devframe/dist/utils/streaming-channel.mjs
4828
4835
  var DEFAULT_HIGH_WATER_MARK = 256;
4829
4836
  var StreamClosedError = class extends Error {
4830
4837
  name = "StreamClosedError";
@@ -5079,7 +5086,7 @@ function toErrorPayload(reason) {
5079
5086
  }
5080
5087
  }
5081
5088
  //#endregion
5082
- //#region node_modules/.pnpm/devframe@1.0.0_@devframes+agentic@1.0.0_cac@7.0.0_srvx@1.0.5/node_modules/devframe/dist/utils/agent-tool-name.mjs
5089
+ //#region node_modules/.pnpm/devframe@1.1.0_@devframes+agentic@1.1.0_cac@7.0.0_srvx@1.0.5/node_modules/devframe/dist/utils/agent-tool-name.mjs
5083
5090
  /**
5084
5091
  * Maximum tool-name length several MCP clients enforce (the Anthropic API
5085
5092
  * pattern is `^[a-zA-Z0-9_-]{1,128}$`).
@@ -5109,7 +5116,7 @@ function toAgentToolName(id) {
5109
5116
  return id.replace(/[^\w-]+/g, "_").slice(0, MAX_TOOL_NAME_LENGTH);
5110
5117
  }
5111
5118
  //#endregion
5112
- //#region node_modules/.pnpm/devframe@1.0.0_@devframes+agentic@1.0.0_cac@7.0.0_srvx@1.0.5/node_modules/devframe/dist/client/index.mjs
5119
+ //#region node_modules/.pnpm/devframe@1.1.0_@devframes+agentic@1.1.0_cac@7.0.0_srvx@1.0.5/node_modules/devframe/dist/client/index.mjs
5113
5120
  /** Devframe runtime routes and static output conventions. */
5114
5121
  var DEVFRAME_CONNECTION_META_FILENAME = "__connection.json";
5115
5122
  /**
@@ -7009,7 +7016,7 @@ async function getDevframeRpcClient(options = {}) {
7009
7016
  bootstrapAuthSettled = true;
7010
7017
  });
7011
7018
  if (connectionMeta.mcp) __vitePreload(async () => {
7012
- const { setupBrowserAgentRpcBridge } = await import("./browser-agent-rpc-BXhoSh1z-DXAVFObe.js");
7019
+ const { setupBrowserAgentRpcBridge } = await import("./browser-agent-rpc-BXhoSh1z-BuCvPGjS.js");
7013
7020
  return { setupBrowserAgentRpcBridge };
7014
7021
  }, [], import.meta.url).then(({ setupBrowserAgentRpcBridge }) => {
7015
7022
  if (!closed) disposeBrowserAgentBridge = setupBrowserAgentRpcBridge(rpc);
@@ -8775,7 +8782,7 @@ var describeHmrReason = (reason) => {
8775
8782
  }
8776
8783
  };
8777
8784
  //#endregion
8778
- //#region node_modules/.pnpm/devframe@1.0.0_@devframes+agentic@1.0.0_cac@7.0.0_srvx@1.0.5/node_modules/devframe/dist/browser-agent-Pu-FLk6I.mjs
8785
+ //#region node_modules/.pnpm/devframe@1.1.0_@devframes+agentic@1.1.0_cac@7.0.0_srvx@1.0.5/node_modules/devframe/dist/browser-agent-Pu-FLk6I.mjs
8779
8786
  var REGISTRY_KEY = Symbol.for("devframe:browser-agent-registry");
8780
8787
  var { tools, listeners: listeners$1 } = globalThis[REGISTRY_KEY] ??= {
8781
8788
  tools: /* @__PURE__ */ new Map(),
@@ -8800,7 +8807,7 @@ function onBrowserAgentToolsChanged(listener) {
8800
8807
  return () => listeners$1.delete(listener);
8801
8808
  }
8802
8809
  //#endregion
8803
- //#region node_modules/.pnpm/devframe@1.0.0_@devframes+agentic@1.0.0_cac@7.0.0_srvx@1.0.5/node_modules/devframe/dist/in-page-channel/index.mjs
8810
+ //#region node_modules/.pnpm/devframe@1.1.0_@devframes+agentic@1.1.0_cac@7.0.0_srvx@1.0.5/node_modules/devframe/dist/in-page-channel/index.mjs
8804
8811
  var diagnostics = /* #__PURE__ */ defineDiagnostics$1({
8805
8812
  docsBase: "https://devfra.me/errors",
8806
8813
  codes: {
@@ -11122,6 +11129,7 @@ var DevtoolsSettings = class DevtoolsSettings extends i$2 {
11122
11129
  return {
11123
11130
  hmrReconnect: s.hmr.reconnect,
11124
11131
  hmrOnIncompatible: s.hmr.onIncompatible,
11132
+ hmrChildState: s.hmr.childState,
11125
11133
  hmrIndicatorVisible: s.hmr.indicatorEnabled,
11126
11134
  hmrIndicatorCount: s.hmr.indicatorCount,
11127
11135
  sourceOverlayEditor: s.sourceOverlay.editor
@@ -11234,6 +11242,7 @@ var DevtoolsSettings = class DevtoolsSettings extends i$2 {
11234
11242
  </p>`;
11235
11243
  const reconnect = o.hmrReconnect ?? s.hmr.reconnect;
11236
11244
  const onIncompatible = o.hmrOnIncompatible ?? s.hmr.onIncompatible;
11245
+ const childState = o.hmrChildState ?? s.hmr.childState;
11237
11246
  const indicatorVisible = o.hmrIndicatorVisible ?? s.hmr.indicatorEnabled;
11238
11247
  const indicatorCount = o.hmrIndicatorCount ?? s.hmr.indicatorCount;
11239
11248
  return b`
@@ -11268,6 +11277,23 @@ var DevtoolsSettings = class DevtoolsSettings extends i$2 {
11268
11277
  ${this._ovrSource("hmrOnIncompatible", s.hmr.onIncompatible)}
11269
11278
  </td>
11270
11279
  </tr>
11280
+ <tr>
11281
+ <td class="key">child state</td>
11282
+ <td class="val">
11283
+ <select
11284
+ @change=${(e) => this._set("hmrChildState", e.target.value)}
11285
+ >
11286
+ ${[
11287
+ "transfer",
11288
+ "reuse",
11289
+ "reset"
11290
+ ].map((mode) => b`<option value=${mode} ?selected=${childState === mode}>
11291
+ ${mode}
11292
+ </option>`)}
11293
+ </select>
11294
+ ${this._ovrSource("hmrChildState", s.hmr.childState)}
11295
+ </td>
11296
+ </tr>
11271
11297
  <tr class=${s.hmr.indicatorEnabled ? "" : "row-disabled"}>
11272
11298
  <td class="key">indicator</td>
11273
11299
  <td class="val">
@@ -11719,4 +11745,4 @@ LitDevtoolsPanel = __decorate([t$2("lit-devtools-panel")], LitDevtoolsPanel);
11719
11745
  //#endregion
11720
11746
  export { onBrowserAgentToolsChanged as n, nanoid as r, listBrowserAgentTools as t };
11721
11747
 
11722
- //# sourceMappingURL=index-DVr5EnyB.js.map
11748
+ //# sourceMappingURL=index-D632jo79.js.map