@rozenite/network-activity-plugin 1.7.0 → 1.8.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 (43) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +24 -0
  3. package/dist/devtools/App.html +2 -2
  4. package/dist/devtools/assets/{App-pokLiGYV.js → App-B3xlUjs6.js} +163 -115
  5. package/dist/devtools/assets/{App-BrSkOkws.css → App-m6xge0az.css} +13 -0
  6. package/dist/react-native/chunks/boot-recording.cjs +307 -28
  7. package/dist/react-native/chunks/boot-recording.js +310 -31
  8. package/dist/react-native/chunks/useNetworkActivityDevTools.require.cjs +192 -141
  9. package/dist/react-native/chunks/useNetworkActivityDevTools.require.js +193 -142
  10. package/dist/react-native/index.d.ts +24 -7
  11. package/dist/rozenite.json +1 -1
  12. package/dist/sdk/index.cjs +127 -0
  13. package/dist/sdk/index.d.ts +1243 -0
  14. package/dist/sdk/index.js +127 -0
  15. package/package.json +17 -6
  16. package/sdk.ts +59 -0
  17. package/src/react-native/__tests__/events-listener.test.ts +35 -0
  18. package/src/react-native/agent/__tests__/network-activity-agent-state.test.ts +21 -9
  19. package/src/react-native/agent/state.ts +13 -13
  20. package/src/react-native/agent/tools.ts +20 -146
  21. package/src/react-native/agent/use-network-activity-agent-tools.ts +73 -64
  22. package/src/react-native/events-listener.ts +12 -3
  23. package/src/react-native/http/http-inspector.ts +19 -5
  24. package/src/react-native/network-inspector.ts +46 -8
  25. package/src/react-native/nitro-fetch/__tests__/nitro-network-inspector.test.ts +198 -0
  26. package/src/react-native/nitro-fetch/nitro-network-inspector.ts +403 -0
  27. package/src/react-native/useHttpInspector.ts +9 -19
  28. package/src/react-native/useNetworkActivityDevTools.ts +13 -1
  29. package/src/react-native/websocket/__tests__/websocket-inspector.test.ts +69 -0
  30. package/src/react-native/websocket/websocket-inspector.ts +32 -17
  31. package/src/shared/agent-tools.ts +230 -0
  32. package/src/shared/client.ts +3 -0
  33. package/src/shared/http-events.ts +6 -0
  34. package/src/shared/websocket-events.ts +16 -7
  35. package/src/ui/components/RequestList.tsx +21 -0
  36. package/src/ui/components/SidePanel.tsx +12 -9
  37. package/src/ui/state/derived.ts +4 -0
  38. package/src/ui/state/model.ts +6 -1
  39. package/src/ui/state/store.ts +52 -36
  40. package/src/ui/tabs/HeadersTab.tsx +18 -4
  41. package/src/ui/tabs/ResponseTab.tsx +5 -3
  42. package/tsconfig.json +4 -1
  43. package/vite.config.ts +7 -0
@@ -37,7 +37,7 @@ const getTypeColor = (type: string) => {
37
37
  const createLegacyNetworkEntry = (
38
38
  selectedRequest: any,
39
39
  httpDetails: any,
40
- wsDetails: any
40
+ wsDetails: any,
41
41
  ): OldNetworkEntry | null => {
42
42
  if (selectedRequest.type === 'http' && httpDetails) {
43
43
  return {
@@ -108,22 +108,22 @@ export const SidePanel = () => {
108
108
  selectedRequest.type === 'http'
109
109
  ? httpDetails?.request?.url || 'Unknown'
110
110
  : selectedRequest.type === 'websocket'
111
- ? wsDetails?.connection?.url || 'Unknown'
112
- : sseDetails?.request?.url || 'Unknown';
111
+ ? wsDetails?.connection?.url || 'Unknown'
112
+ : sseDetails?.request?.url || 'Unknown';
113
113
 
114
114
  // Extract status from the request
115
115
  const requestStatus =
116
116
  selectedRequest.type === 'http'
117
117
  ? httpDetails?.response?.status || httpDetails?.status || 'pending'
118
118
  : selectedRequest.type === 'websocket'
119
- ? wsDetails?.status || 'unknown'
120
- : sseDetails?.status || 'unknown';
119
+ ? wsDetails?.status || 'unknown'
120
+ : sseDetails?.status || 'unknown';
121
121
 
122
122
  // Create legacy network entry for tab components
123
123
  const legacyEntry = createLegacyNetworkEntry(
124
124
  selectedRequest,
125
125
  httpDetails,
126
- wsDetails
126
+ wsDetails,
127
127
  );
128
128
  const legacyNetworkEntries = new Map<string, OldNetworkEntry>();
129
129
  if (legacyEntry) {
@@ -131,7 +131,9 @@ export const SidePanel = () => {
131
131
  }
132
132
 
133
133
  const override = legacyEntry !== null ? overrides.get(legacyEntry.url) : null;
134
- const hasResponseOverride = override && override.body ? true : false;
134
+ const supportsOverrides = httpDetails?.source !== 'nitro';
135
+ const hasResponseOverride =
136
+ supportsOverrides && override && override.body ? true : false;
135
137
 
136
138
  const getTabsListTriggers = () => {
137
139
  if (httpDetails) {
@@ -226,6 +228,7 @@ export const SidePanel = () => {
226
228
  <TabsContent value="response" className="flex-1 m-0 overflow-hidden">
227
229
  <ResponseTab
228
230
  selectedRequest={httpDetails}
231
+ supportsOverrides={supportsOverrides}
229
232
  onRequestResponseBody={(requestId) => {
230
233
  if (client) {
231
234
  client.send('get-response-body', {
@@ -289,14 +292,14 @@ export const SidePanel = () => {
289
292
  <div className="flex items-center gap-2 min-w-0 flex-1">
290
293
  <div
291
294
  className={`w-3 h-3 rounded-full flex-shrink-0 ${getTypeColor(
292
- selectedRequest.type
295
+ selectedRequest.type,
293
296
  )}`}
294
297
  ></div>
295
298
  <span className="font-medium truncate">{requestName}</span>
296
299
  <Badge
297
300
  variant="outline"
298
301
  className={`${getStatusColor(
299
- requestStatus
302
+ requestStatus,
300
303
  )} border-current flex-shrink-0`}
301
304
  >
302
305
  {requestStatus}
@@ -17,6 +17,7 @@ export const getProcessedRequests = memoize((state: NetworkActivityState) => {
17
17
  requests.push({
18
18
  id: httpEntry.id,
19
19
  type: 'http',
20
+ source: httpEntry.source,
20
21
  name: httpEntry.request.url,
21
22
  status: httpEntry.status,
22
23
  timestamp: httpEntry.timestamp,
@@ -31,6 +32,7 @@ export const getProcessedRequests = memoize((state: NetworkActivityState) => {
31
32
  requests.push({
32
33
  id: wsEntry.id,
33
34
  type: 'websocket',
35
+ source: wsEntry.source,
34
36
  name: wsEntry.connection.url,
35
37
  status: wsEntry.status,
36
38
  timestamp: wsEntry.timestamp,
@@ -77,6 +79,7 @@ export const getRequestSummary = (
77
79
  return {
78
80
  id: httpEntry.id,
79
81
  type: 'http',
82
+ source: httpEntry.source,
80
83
  name: httpEntry.request.url,
81
84
  status: httpEntry.status,
82
85
  timestamp: httpEntry.timestamp,
@@ -91,6 +94,7 @@ export const getRequestSummary = (
91
94
  return {
92
95
  id: wsEntry.id,
93
96
  type: 'websocket',
97
+ source: wsEntry.source,
94
98
  name: wsEntry.connection.url,
95
99
  status: wsEntry.status,
96
100
  timestamp: wsEntry.timestamp,
@@ -3,11 +3,12 @@ import {
3
3
  ResourceType,
4
4
  HttpHeaders,
5
5
  RequestPostData,
6
+ NetworkEventSource,
6
7
  } from '../../shared/client';
7
8
 
8
9
  export type RequestId = string;
9
10
  export type Timestamp = number;
10
- export type SocketId = number;
11
+ export type SocketId = string;
11
12
  export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD';
12
13
 
13
14
  export type NetworkEntryType = 'http' | 'websocket' | 'sse';
@@ -47,6 +48,7 @@ export type HttpNetworkEntry = {
47
48
  id: RequestId;
48
49
  type: 'http';
49
50
  timestamp: Timestamp;
51
+ source?: NetworkEventSource;
50
52
  duration?: number;
51
53
 
52
54
  request: HttpRequest;
@@ -79,6 +81,7 @@ export type SSENetworkEntry = {
79
81
  id: RequestId;
80
82
  type: 'sse';
81
83
  timestamp: Timestamp;
84
+ source?: NetworkEventSource;
82
85
  duration?: number;
83
86
 
84
87
  request: HttpRequest;
@@ -117,6 +120,7 @@ export type WebSocketNetworkEntry = {
117
120
  id: RequestId;
118
121
  type: 'websocket';
119
122
  timestamp: Timestamp;
123
+ source?: NetworkEventSource;
120
124
  duration?: number;
121
125
 
122
126
  connection: WebSocketConnection;
@@ -135,6 +139,7 @@ export type NetworkEntry =
135
139
  export type ProcessedRequest = {
136
140
  id: RequestId;
137
141
  type: NetworkEntryType;
142
+ source?: NetworkEventSource;
138
143
  name: string;
139
144
  status: HttpStatus | WebSocketStatus | SSEStatus;
140
145
  timestamp: Timestamp;
@@ -50,7 +50,7 @@ export interface NetworkActivityState {
50
50
  // Event handling
51
51
  handleEvent: <K extends keyof NetworkActivityEventMap>(
52
52
  eventType: K,
53
- data: NetworkActivityEventMap[K]
53
+ data: NetworkActivityEventMap[K],
54
54
  ) => void;
55
55
 
56
56
  // Client management
@@ -80,7 +80,7 @@ export const createNetworkActivityStore = () =>
80
80
 
81
81
  _client.send(
82
82
  isRecording ? 'network-enable' : 'network-disable',
83
- {}
83
+ {},
84
84
  );
85
85
  set({ isRecording });
86
86
  },
@@ -120,11 +120,22 @@ export const createNetworkActivityStore = () =>
120
120
  // Event handling
121
121
  handleEvent: <K extends keyof NetworkActivityEventMap>(
122
122
  eventType: K,
123
- data: NetworkActivityEventMap[K]
123
+ data: NetworkActivityEventMap[K],
124
124
  ) => {
125
125
  switch (eventType) {
126
+ case 'recording-state': {
127
+ const eventData =
128
+ data as NetworkActivityEventMap['recording-state'];
129
+ const { isRecording, _client } = get();
130
+ if (_client && isRecording !== eventData.isRecording) {
131
+ _client.send(isRecording ? 'network-enable' : 'network-disable', {});
132
+ }
133
+ break;
134
+ }
135
+
126
136
  case 'client-ui-settings': {
127
- const eventData = data as NetworkActivityEventMap['client-ui-settings'];
137
+ const eventData =
138
+ data as NetworkActivityEventMap['client-ui-settings'];
128
139
  set({ clientUISettings: eventData.settings || null });
129
140
  break;
130
141
  }
@@ -135,7 +146,7 @@ export const createNetworkActivityStore = () =>
135
146
  const headersWithContentType =
136
147
  applyReactNativeRequestHeadersLogic(
137
148
  eventData.request.headers,
138
- eventData.request.postData
149
+ eventData.request.postData,
139
150
  );
140
151
 
141
152
  const requestContentType =
@@ -145,6 +156,7 @@ export const createNetworkActivityStore = () =>
145
156
  id: eventData.requestId,
146
157
  type: 'http',
147
158
  timestamp: eventData.timestamp,
159
+ source: eventData.source ?? 'builtin',
148
160
  request: {
149
161
  url: eventData.request.url,
150
162
  method: eventData.request.method,
@@ -280,7 +292,7 @@ export const createNetworkActivityStore = () =>
280
292
  ? {
281
293
  type:
282
294
  getContentTypeMime(
283
- httpEntry.response?.headers ?? {}
295
+ httpEntry.response?.headers ?? {},
284
296
  ) || 'text/plain',
285
297
  data: eventData.body,
286
298
  }
@@ -304,6 +316,7 @@ export const createNetworkActivityStore = () =>
304
316
  id: `ws-${eventData.socketId}`,
305
317
  type: 'websocket',
306
318
  timestamp: eventData.timestamp,
319
+ source: eventData.source ?? 'builtin',
307
320
  connection: {
308
321
  url: eventData.url,
309
322
  socketId: eventData.socketId,
@@ -332,7 +345,7 @@ export const createNetworkActivityStore = () =>
332
345
  data as NetworkActivityEventMap['websocket-open'];
333
346
  set((state) => {
334
347
  const entry = state.networkEntries.get(
335
- `ws-${eventData.socketId}`
348
+ `ws-${eventData.socketId}`,
336
349
  );
337
350
  if (!entry || entry.type !== 'websocket') return state;
338
351
 
@@ -354,7 +367,7 @@ export const createNetworkActivityStore = () =>
354
367
  data as NetworkActivityEventMap['websocket-close'];
355
368
  set((state) => {
356
369
  const entry = state.networkEntries.get(
357
- `ws-${eventData.socketId}`
370
+ `ws-${eventData.socketId}`,
358
371
  );
359
372
  if (!entry || entry.type !== 'websocket') return state;
360
373
 
@@ -394,8 +407,8 @@ export const createNetworkActivityStore = () =>
394
407
  newMessages.set(
395
408
  socketId,
396
409
  [...currentMessages, message].slice(
397
- -MAX_WEBSOCKET_MESSAGES_PER_CONNECTION
398
- )
410
+ -MAX_WEBSOCKET_MESSAGES_PER_CONNECTION,
411
+ ),
399
412
  );
400
413
 
401
414
  return { websocketMessages: newMessages };
@@ -423,8 +436,8 @@ export const createNetworkActivityStore = () =>
423
436
  newMessages.set(
424
437
  socketId,
425
438
  [...currentMessages, message].slice(
426
- -MAX_WEBSOCKET_MESSAGES_PER_CONNECTION
427
- )
439
+ -MAX_WEBSOCKET_MESSAGES_PER_CONNECTION,
440
+ ),
428
441
  );
429
442
 
430
443
  return { websocketMessages: newMessages };
@@ -437,7 +450,7 @@ export const createNetworkActivityStore = () =>
437
450
  data as NetworkActivityEventMap['websocket-error'];
438
451
  set((state) => {
439
452
  const entry = state.networkEntries.get(
440
- `ws-${eventData.socketId}`
453
+ `ws-${eventData.socketId}`,
441
454
  );
442
455
  if (!entry || entry.type !== 'websocket') return state;
443
456
 
@@ -460,7 +473,7 @@ export const createNetworkActivityStore = () =>
460
473
  data as NetworkActivityEventMap['websocket-connection-status-changed'];
461
474
  set((state) => {
462
475
  const entry = state.networkEntries.get(
463
- `ws-${eventData.socketId}`
476
+ `ws-${eventData.socketId}`,
464
477
  );
465
478
  if (!entry || entry.type !== 'websocket') return state;
466
479
 
@@ -520,7 +533,7 @@ export const createNetworkActivityStore = () =>
520
533
  const updatedEntry: SSENetworkEntry = {
521
534
  ...sseEntry,
522
535
  messages: [...sseEntry.messages, newMessage].slice(
523
- -MAX_SSE_MESSAGES_PER_CONNECTION
536
+ -MAX_SSE_MESSAGES_PER_CONNECTION,
524
537
  ),
525
538
  };
526
539
 
@@ -580,59 +593,62 @@ export const createNetworkActivityStore = () =>
580
593
 
581
594
  // Subscribe to all events using the unified handler
582
595
  const unsubscribeFunctions = [
596
+ client.onMessage('recording-state', (data) =>
597
+ handleEvent('recording-state', data)
598
+ ),
583
599
  client.onMessage('client-ui-settings', (data) =>
584
- handleEvent('client-ui-settings', data)
600
+ handleEvent('client-ui-settings', data),
585
601
  ),
586
602
  client.onMessage('request-sent', (data) =>
587
- handleEvent('request-sent', data)
603
+ handleEvent('request-sent', data),
588
604
  ),
589
605
  client.onMessage('request-progress', (data) =>
590
- handleEvent('request-progress', data)
606
+ handleEvent('request-progress', data),
591
607
  ),
592
608
  client.onMessage('response-received', (data) =>
593
- handleEvent('response-received', data)
609
+ handleEvent('response-received', data),
594
610
  ),
595
611
  client.onMessage('request-completed', (data) =>
596
- handleEvent('request-completed', data)
612
+ handleEvent('request-completed', data),
597
613
  ),
598
614
  client.onMessage('request-failed', (data) =>
599
- handleEvent('request-failed', data)
615
+ handleEvent('request-failed', data),
600
616
  ),
601
617
  client.onMessage('response-body', (data) =>
602
- handleEvent('response-body', data)
618
+ handleEvent('response-body', data),
603
619
  ),
604
620
  client.onMessage('websocket-connect', (data) =>
605
- handleEvent('websocket-connect', data)
621
+ handleEvent('websocket-connect', data),
606
622
  ),
607
623
  client.onMessage('websocket-open', (data) =>
608
- handleEvent('websocket-open', data)
624
+ handleEvent('websocket-open', data),
609
625
  ),
610
626
  client.onMessage('websocket-close', (data) =>
611
- handleEvent('websocket-close', data)
627
+ handleEvent('websocket-close', data),
612
628
  ),
613
629
  client.onMessage('websocket-message-sent', (data) =>
614
- handleEvent('websocket-message-sent', data)
630
+ handleEvent('websocket-message-sent', data),
615
631
  ),
616
632
  client.onMessage('websocket-message-received', (data) =>
617
- handleEvent('websocket-message-received', data)
633
+ handleEvent('websocket-message-received', data),
618
634
  ),
619
635
  client.onMessage('websocket-error', (data) =>
620
- handleEvent('websocket-error', data)
636
+ handleEvent('websocket-error', data),
621
637
  ),
622
638
  client.onMessage('websocket-connection-status-changed', (data) =>
623
- handleEvent('websocket-connection-status-changed', data)
639
+ handleEvent('websocket-connection-status-changed', data),
624
640
  ),
625
641
  client.onMessage('sse-open', (data) =>
626
- handleEvent('sse-open', data)
642
+ handleEvent('sse-open', data),
627
643
  ),
628
644
  client.onMessage('sse-message', (data) =>
629
- handleEvent('sse-message', data)
645
+ handleEvent('sse-message', data),
630
646
  ),
631
647
  client.onMessage('sse-error', (data) =>
632
- handleEvent('sse-error', data)
648
+ handleEvent('sse-error', data),
633
649
  ),
634
650
  client.onMessage('sse-close', (data) =>
635
- handleEvent('sse-close', data)
651
+ handleEvent('sse-close', data),
636
652
  ),
637
653
  ];
638
654
 
@@ -651,7 +667,7 @@ export const createNetworkActivityStore = () =>
651
667
 
652
668
  if (_unsubscribeFunctions) {
653
669
  _unsubscribeFunctions.forEach(
654
- (unsubscribe: { remove: () => void }) => unsubscribe.remove()
670
+ (unsubscribe: { remove: () => void }) => unsubscribe.remove(),
655
671
  );
656
672
  }
657
673
 
@@ -693,8 +709,8 @@ export const createNetworkActivityStore = () =>
693
709
  },
694
710
  }),
695
711
  partialize: (state) => ({ overrides: state.overrides }), // Persist only the overrides
696
- }
697
- )
712
+ },
713
+ ),
698
714
  );
699
715
 
700
716
  export const store = createNetworkActivityStore();
@@ -17,7 +17,7 @@ function getHeadersItems(headers?: HttpHeaders): KeyValueItem[] {
17
17
  return Object.entries(headers).reduce<KeyValueItem[]>((acc, [key, value]) => {
18
18
  if (Array.isArray(value)) {
19
19
  acc.push(
20
- ...value.map((item) => ({ key: key.toLowerCase(), value: item }))
20
+ ...value.map((item) => ({ key: key.toLowerCase(), value: item })),
21
21
  );
22
22
  } else {
23
23
  acc.push({ key: key.toLowerCase(), value: value });
@@ -29,6 +29,12 @@ function getHeadersItems(headers?: HttpHeaders): KeyValueItem[] {
29
29
 
30
30
  export const HeadersTab = ({ selectedRequest }: HeadersTabProps) => {
31
31
  const requestBody = selectedRequest.request.body;
32
+ const sourceLabel =
33
+ selectedRequest.source === 'nitro'
34
+ ? 'Nitro'
35
+ : selectedRequest.source === 'builtin'
36
+ ? 'Built-in'
37
+ : null;
32
38
 
33
39
  const generalItems: KeyValueItem[] = useMemo(
34
40
  () => [
@@ -55,18 +61,26 @@ export const HeadersTab = ({ selectedRequest }: HeadersTabProps) => {
55
61
  },
56
62
  ]
57
63
  : []),
64
+ ...(sourceLabel
65
+ ? [
66
+ {
67
+ key: 'Source',
68
+ value: sourceLabel,
69
+ },
70
+ ]
71
+ : []),
58
72
  ],
59
- [selectedRequest]
73
+ [requestBody, selectedRequest, sourceLabel],
60
74
  );
61
75
 
62
76
  const responseHeadersItems = useMemo(
63
77
  () => getHeadersItems(selectedRequest.response?.headers),
64
- [selectedRequest]
78
+ [selectedRequest],
65
79
  );
66
80
 
67
81
  const requestHeadersItems = useMemo(
68
82
  () => getHeadersItems(selectedRequest.request.headers),
69
- [selectedRequest]
83
+ [selectedRequest],
70
84
  );
71
85
 
72
86
  return (
@@ -13,6 +13,7 @@ import { Pencil } from 'lucide-react';
13
13
 
14
14
  export type ResponseTabProps = {
15
15
  selectedRequest: HttpNetworkEntry;
16
+ supportsOverrides?: boolean;
16
17
  onRequestResponseBody: (requestId: string) => void;
17
18
  };
18
19
 
@@ -34,6 +35,7 @@ const RenderResponseBodySection = ({
34
35
 
35
36
  export const ResponseTab = ({
36
37
  selectedRequest,
38
+ supportsOverrides = true,
37
39
  onRequestResponseBody,
38
40
  }: ResponseTabProps) => {
39
41
  const onRequestResponseBodyRef = useRef(onRequestResponseBody);
@@ -81,7 +83,7 @@ export const ResponseTab = ({
81
83
  />
82
84
  );
83
85
 
84
- const overrideAction = (
86
+ const overrideAction = supportsOverrides ? (
85
87
  <Button
86
88
  variant="ghost"
87
89
  size="xs"
@@ -96,9 +98,9 @@ export const ResponseTab = ({
96
98
  <Pencil className="h-2 w-2" />
97
99
  Override
98
100
  </Button>
99
- );
101
+ ) : null;
100
102
 
101
- if (initialOverride !== undefined) {
103
+ if (supportsOverrides && initialOverride !== undefined) {
102
104
  return (
103
105
  <OverrideResponse
104
106
  selectedRequest={selectedRequest}
package/tsconfig.json CHANGED
@@ -11,12 +11,15 @@
11
11
  "noFallthroughCasesInSwitch": true,
12
12
  "module": "ESNext",
13
13
  "moduleResolution": "bundler",
14
+ "paths": {
15
+ "@rozenite/agent-shared": ["../agent-shared/src/index.ts"]
16
+ },
14
17
  "resolveJsonModule": true,
15
18
  "isolatedModules": true,
16
19
  "noEmit": true,
17
20
  "jsx": "react-jsx"
18
21
  },
19
- "include": ["src/**/*", "react-native.ts", "rozenite.config.ts"],
22
+ "include": ["src/**/*", "react-native.ts", "sdk.ts", "rozenite.config.ts"],
20
23
  "exclude": ["node_modules", "dist", "build"],
21
24
  "references": [
22
25
  {
package/vite.config.ts CHANGED
@@ -1,10 +1,17 @@
1
1
  /// <reference types='vitest' />
2
+ import { resolve } from 'node:path';
2
3
  import { defineConfig } from 'vite';
3
4
  import { rozenitePlugin } from '@rozenite/vite-plugin';
4
5
 
5
6
  export default defineConfig({
6
7
  root: __dirname,
7
8
  plugins: [rozenitePlugin()],
9
+ test: {
10
+ passWithNoTests: true,
11
+ alias: {
12
+ '@rozenite/agent-shared': resolve(__dirname, '../agent-shared/src/index.ts'),
13
+ },
14
+ },
8
15
  base: './',
9
16
  build: {
10
17
  outDir: './dist',