@oddsquad/vite-plugin-lit 0.4.0 → 0.6.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 (100) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/README.md +16 -5
  3. package/bin.mjs +16 -12
  4. package/dist/client/assets/{browser-agent-rpc-BXhoSh1z-CdtPhBL-.js → browser-agent-rpc-BXhoSh1z-DXAVFObe.js} +2 -2
  5. package/dist/client/assets/{browser-agent-rpc-BXhoSh1z-CdtPhBL-.js.map → browser-agent-rpc-BXhoSh1z-DXAVFObe.js.map} +1 -1
  6. package/dist/client/assets/{index-DVe6M4HV.js → index-DVr5EnyB.js} +1859 -751
  7. package/dist/client/assets/index-DVr5EnyB.js.map +1 -0
  8. package/dist/client/index.html +11 -1
  9. package/lib/devframe/definition.d.ts +7 -0
  10. package/lib/devframe/definition.d.ts.map +1 -1
  11. package/lib/devframe/definition.js +56 -11
  12. package/lib/devframe/definition.js.map +1 -1
  13. package/lib/devframe/launch-editor.d.ts +20 -0
  14. package/lib/devframe/launch-editor.d.ts.map +1 -0
  15. package/lib/devframe/launch-editor.js +40 -0
  16. package/lib/devframe/launch-editor.js.map +1 -0
  17. package/lib/devframe/protocol.d.ts +31 -4
  18. package/lib/devframe/protocol.d.ts.map +1 -1
  19. package/lib/devframe/protocol.js +21 -3
  20. package/lib/devframe/protocol.js.map +1 -1
  21. package/lib/devframe/rpc-source.d.ts +44 -0
  22. package/lib/devframe/rpc-source.d.ts.map +1 -0
  23. package/lib/devframe/rpc-source.js +150 -0
  24. package/lib/devframe/rpc-source.js.map +1 -0
  25. package/lib/devframe/source.d.ts +12 -0
  26. package/lib/devframe/source.d.ts.map +1 -1
  27. package/lib/devframe/source.js +12 -0
  28. package/lib/devframe/source.js.map +1 -1
  29. package/lib/devframe/vite.d.ts +2 -0
  30. package/lib/devframe/vite.d.ts.map +1 -1
  31. package/lib/devframe/vite.js +3 -9
  32. package/lib/devframe/vite.js.map +1 -1
  33. package/lib/options.d.ts +6 -1
  34. package/lib/options.d.ts.map +1 -1
  35. package/lib/options.js +65 -18
  36. package/lib/options.js.map +1 -1
  37. package/lib/override-baselines.d.ts +17 -0
  38. package/lib/override-baselines.d.ts.map +1 -0
  39. package/lib/override-baselines.js +25 -0
  40. package/lib/override-baselines.js.map +1 -0
  41. package/lib/plugin.d.ts.map +1 -1
  42. package/lib/plugin.js +8 -0
  43. package/lib/plugin.js.map +1 -1
  44. package/lib/plugins/open-in-editor.d.ts.map +1 -1
  45. package/lib/plugins/open-in-editor.js +6 -1
  46. package/lib/plugins/open-in-editor.js.map +1 -1
  47. package/lib/runtime/indicator.js.map +1 -1
  48. package/lib/runtime/inspector/install.js +4 -2
  49. package/lib/runtime/inspector/install.js.map +1 -1
  50. package/lib/runtime/inspector/serialize.d.ts.map +1 -1
  51. package/lib/runtime/inspector/serialize.js +20 -0
  52. package/lib/runtime/inspector/serialize.js.map +1 -1
  53. package/lib/runtime/overrides.d.ts +4 -10
  54. package/lib/runtime/overrides.d.ts.map +1 -1
  55. package/lib/runtime/overrides.js +5 -3
  56. package/lib/runtime/overrides.js.map +1 -1
  57. package/lib/runtime/page-channel.d.ts +52 -0
  58. package/lib/runtime/page-channel.d.ts.map +1 -0
  59. package/lib/runtime/page-channel.js +67 -0
  60. package/lib/runtime/page-channel.js.map +1 -0
  61. package/lib/runtime/patch.d.ts.map +1 -1
  62. package/lib/runtime/patch.js +2 -1
  63. package/lib/runtime/patch.js.map +1 -1
  64. package/lib/runtime/rpc-transport.d.ts +46 -0
  65. package/lib/runtime/rpc-transport.d.ts.map +1 -0
  66. package/lib/runtime/rpc-transport.js +82 -0
  67. package/lib/runtime/rpc-transport.js.map +1 -0
  68. package/lib/runtime/source-overlay/overlay-element.d.ts.map +1 -1
  69. package/lib/runtime/source-overlay/overlay-element.js +13 -3
  70. package/lib/runtime/source-overlay/overlay-element.js.map +1 -1
  71. package/lib/runtime/timeline/chrome-tracks.d.ts +22 -0
  72. package/lib/runtime/timeline/chrome-tracks.d.ts.map +1 -0
  73. package/lib/runtime/timeline/chrome-tracks.js +74 -0
  74. package/lib/runtime/timeline/chrome-tracks.js.map +1 -0
  75. package/lib/runtime/timeline/clock.d.ts +6 -0
  76. package/lib/runtime/timeline/clock.d.ts.map +1 -1
  77. package/lib/runtime/timeline/clock.js +6 -0
  78. package/lib/runtime/timeline/clock.js.map +1 -1
  79. package/lib/runtime/timeline/install.js +42 -13
  80. package/lib/runtime/timeline/install.js.map +1 -1
  81. package/lib/runtime/timeline/public-api.d.ts.map +1 -1
  82. package/lib/runtime/timeline/public-api.js +11 -3
  83. package/lib/runtime/timeline/public-api.js.map +1 -1
  84. package/lib/runtime/timeline/transport.d.ts +6 -9
  85. package/lib/runtime/timeline/transport.d.ts.map +1 -1
  86. package/lib/runtime/timeline/transport.js.map +1 -1
  87. package/lib/timeline/filter.d.ts +38 -0
  88. package/lib/timeline/filter.d.ts.map +1 -0
  89. package/lib/timeline/filter.js +44 -0
  90. package/lib/timeline/filter.js.map +1 -0
  91. package/lib/timeline/tracks.d.ts +113 -0
  92. package/lib/timeline/tracks.d.ts.map +1 -0
  93. package/lib/timeline/tracks.js +168 -0
  94. package/lib/timeline/tracks.js.map +1 -0
  95. package/package.json +6 -1
  96. package/types/timeline.d.ts +44 -0
  97. package/types/timeline.d.ts.map +1 -1
  98. package/types/timeline.js +2 -0
  99. package/types/timeline.js.map +1 -1
  100. package/dist/client/assets/index-DVe6M4HV.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -3,6 +3,91 @@
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.6.0 — 2026-09-29
7
+
8
+ A small release with one feature. The Lit timeline can now appear in Chrome
9
+ DevTools' own Performance panel, so an update tick sits on the same time axis
10
+ as the layout, paint and long tasks it caused.
11
+
12
+ ### Added
13
+
14
+ - **Lit updates in Chrome's Performance panel.** Turn on **chrome performance
15
+ tracks** under Timeline in the Settings tab and a Chrome Performance
16
+ recording gets a Lit track group, with each update tick nested as
17
+ `<my-element> performUpdate` over its phases, next to layout, paint and
18
+ long tasks. It works without the Lit panel recording, and traces taken
19
+ through chrome-devtools-mcp include it.
20
+
21
+ ## 0.5.0 — 2026-09-29
22
+
23
+ The timeline gets a second view: Tracks, one lane per layer on a shared time
24
+ axis. The Settings tab now says where each value came from and flags overrides
25
+ the config has since moved past. Timeline events can be linked to, a reloaded
26
+ panel keeps what was recorded, and both the panel and the in-page overlay open
27
+ source links in the editor you picked.
28
+
29
+ ### Added
30
+
31
+ - **Tracks view for the timeline.** A List | Tracks switch in the Timeline
32
+ toolbar draws the recording as one horizontal lane per layer on a shared time
33
+ axis, so concurrency, gaps and rhythm are visible: which layers fire
34
+ together, how a click lines up with the update it caused. Overlapping spans
35
+ stack, so an update tick reads as `performUpdate` with its phases beneath it,
36
+ and marks never get narrower than 2px. Wheel zooms around the pointer, drag
37
+ pans, double-click fits the whole recording, and a fitted view follows the
38
+ live edge while recording. A chip strip picks which lanes to draw; it is a
39
+ view filter, not the capture toggle. Both views share one selection and one
40
+ detail pane.
41
+ - **Where each setting came from.** Settings rows read like "Zed (env)",
42
+ "VS Code (default)" or "Cursor (option)". An overridden row names the
43
+ baseline it replaced and has its own reset. An unknown
44
+ `LIT_PLUGIN_SOURCE_OVERLAY_EDITOR` value now logs a warning and falls back to
45
+ the default.
46
+ - **A hint when the config moved under an override.** An override remembers
47
+ the value it was made against. If that config value has since changed, the
48
+ row says "Config changed since you overrode this: was X, now Y", with Reset
49
+ (let the new config apply) and Keep (hide the hint, keep the override).
50
+ - **Links to timeline events.** Selecting a row puts `#event=<id>` in the
51
+ hash; opening that link selects the span and scrolls it into view, in a live
52
+ session or an exported snapshot. An id the buffer no longer holds opens the
53
+ Timeline with nothing selected.
54
+ - **Temporal values in the inspector** preview as their kind plus ISO form,
55
+ e.g. `Temporal.PlainDate(2026-09-29)`, instead of an empty object. This works
56
+ with native Temporal and with polyfills.
57
+ - **The standalone `lit-devtools dev` server can be fed from a live page.** A
58
+ page calls `connectToDevServer()` (from `@oddsquad/vite-plugin-lit/connect.js`)
59
+ to send its tree, inspector and timeline traffic to the server's panel over
60
+ devframe RPC. `lit-devtools dev --no-auth` skips the one-time code. Pages not
61
+ served by Vite, and cross-origin pages, are not covered yet.
62
+
63
+ ### Changed
64
+
65
+ - **The timeline's element and regex filters apply to Tracks too**, so
66
+ switching views mid-investigation no longer brings back everything you
67
+ filtered out. A filter that hides the selected mark keeps its detail pane
68
+ open, as the List always did.
69
+
70
+ ### Fixed
71
+
72
+ - **A reloaded live panel keeps the recorded events.** Reloading or first
73
+ opening the panel mid-session used to show "No events recorded." while the
74
+ dev server still held them, and a cold `#event=` link could not resolve. The
75
+ panel now fills itself from the server's buffer when it connects, without
76
+ duplicates, and events you cleared stay cleared across a reload.
77
+ - **Source links open in the editor you chose.** The editor picked through
78
+ `sourceOverlay.editor`, `LIT_PLUGIN_SOURCE_OVERLAY_EDITOR` or the Settings
79
+ tab only shaped the overlay's URL scheme; clicks from the panel and the
80
+ in-page overlay let launch-editor guess, so picking Cursor could open VS
81
+ Code. Both now pass the chosen editor (`vscode`, `cursor`, `zed`, `idea`).
82
+ Windsurf, custom editors and projects that never named one still
83
+ auto-detect.
84
+ - **Exported snapshots contain the whole event buffer**, not the last 50
85
+ events, so every row in an export can be linked to.
86
+ - **A linked timeline row scrolls into view on a cold open** instead of
87
+ leaving the list pinned to its newest row.
88
+ - **The panel has a favicon**, so opening it in its own tab no longer logs a
89
+ 404 for `/favicon.ico`.
90
+
6
91
  ## 0.4.0 — 2026-09-29
7
92
 
8
93
  A maintenance release. The timeline panel stays fast with a full buffer, the
package/README.md CHANGED
@@ -118,11 +118,22 @@ The two differ in how the server is found, not in what it can do:
118
118
  discovery at all. Reach for it if registry discovery is unavailable — the
119
119
  plugin logs a warning saying so at startup, naming the reason.
120
120
 
121
- The CLI also has `lit-devtools dev`, a standalone devframe server with no page
122
- attached. It exists to prove the panel definition runs without Vite (a
123
- framework-neutrality harness, and the groundwork for non-Vite adapters); it
124
- cannot show a real component tree, so it is not a way to inspect an app
125
- without a dev server.
121
+ 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';
128
+
129
+ await connectToDevServer('http://localhost:5180/');
130
+ ```
131
+
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.
126
137
 
127
138
  ## Playground
128
139
 
package/bin.mjs CHANGED
@@ -31,8 +31,7 @@
31
31
  */
32
32
 
33
33
  import process from 'node:process';
34
- import {createLitDevframe} from './lib/devframe/definition.js';
35
- import {createNullSource} from './lib/devframe/source.js';
34
+ import {createStandaloneLitDevframe} from './lib/devframe/rpc-source.js';
36
35
  import {PACKAGE_VERSION} from './lib/devframe/paths.js';
37
36
 
38
37
  /**
@@ -62,25 +61,30 @@ const main = async () => {
62
61
  const cli = cac('lit-devtools');
63
62
 
64
63
  cli
65
- .command('dev', 'Start a standalone devframe dev server (no page attached)')
64
+ .command(
65
+ 'dev',
66
+ 'Start a standalone devframe dev server that pages connect to'
67
+ )
66
68
  .option('--port <port>', 'Port to listen on', {default: DEFAULT_DEV_PORT})
67
69
  .option('--host <host>', 'Host to bind to', {default: 'localhost'})
68
70
  .option('--open', 'Open the browser on start')
71
+ .option(
72
+ '--no-auth',
73
+ 'Skip the one-time-code gate, so a page can connect without a token'
74
+ )
69
75
  .action(async (flags) => {
70
76
  const {createDevServer} = await import('devframe/adapters/dev');
71
- // A standalone server has no Vite and no page, so the component tree
72
- // is empty by construction. This command is a framework-neutrality
73
- // harness for the definition, not a way to inspect a real app --
74
- // for that, run your Vite dev server with DevTools enabled.
77
+ // 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.
75
82
  await createDevServer(
76
- createLitDevframe({
77
- source: createNullSource(),
78
- version: PACKAGE_VERSION,
79
- }),
83
+ createStandaloneLitDevframe({version: PACKAGE_VERSION}),
80
84
  {
81
85
  host: flags.host,
82
86
  port: Number(flags.port),
83
- flags: {open: Boolean(flags.open)},
87
+ flags: {open: Boolean(flags.open), auth: flags.auth},
84
88
  }
85
89
  );
86
90
  });
@@ -1,4 +1,4 @@
1
- import { n as onBrowserAgentToolsChanged, r as nanoid, t as listBrowserAgentTools } from "./index-DVe6M4HV.js";
1
+ import { n as onBrowserAgentToolsChanged, r as nanoid, t as listBrowserAgentTools } from "./index-DVr5EnyB.js";
2
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
3
3
  var CLIENT_ID_STORAGE_KEY = "devframe:client-id";
4
4
  var memoryClientId;
@@ -66,4 +66,4 @@ function setupBrowserAgentRpcBridge(rpc) {
66
66
  //#endregion
67
67
  export { setupBrowserAgentRpcBridge };
68
68
 
69
- //# sourceMappingURL=browser-agent-rpc-BXhoSh1z-CdtPhBL-.js.map
69
+ //# sourceMappingURL=browser-agent-rpc-BXhoSh1z-DXAVFObe.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"browser-agent-rpc-BXhoSh1z-CdtPhBL-.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-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"}