1+ import { readFileSync } from 'node:fs' ;
2+
3+ const escapeRegex = ( value ) => value . replace ( / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g, '\\$&' ) ;
4+
5+ const chatTransportContractPath = new URL (
6+ '../../src-tauri/src/desktop_bridge_chat_transport_contract.json' ,
7+ import . meta. url ,
8+ ) ;
9+ const chatTransportContract = JSON . parse ( readFileSync ( chatTransportContractPath , 'utf8' ) ) ;
10+ const CHAT_TRANSPORT_MODE_STORAGE_KEY = chatTransportContract . storageKey ;
11+ const CHAT_TRANSPORT_MODE_WEBSOCKET = chatTransportContract . websocketValue ;
12+
13+ if (
14+ typeof CHAT_TRANSPORT_MODE_STORAGE_KEY !== 'string' ||
15+ ! CHAT_TRANSPORT_MODE_STORAGE_KEY ||
16+ typeof CHAT_TRANSPORT_MODE_WEBSOCKET !== 'string' ||
17+ ! CHAT_TRANSPORT_MODE_WEBSOCKET
18+ ) {
19+ throw new Error (
20+ 'desktop bridge chat transport contract must define non-empty string storageKey and websocketValue fields' ,
21+ ) ;
22+ }
23+
24+ const CHAT_TRANSPORT_STORAGE_KEY_PATTERN = escapeRegex ( CHAT_TRANSPORT_MODE_STORAGE_KEY ) ;
25+ const CHAT_TRANSPORT_WEBSOCKET_PATTERN = escapeRegex ( CHAT_TRANSPORT_MODE_WEBSOCKET ) ;
26+ const CHAT_TRANSPORT_READ_HINT =
27+ `Expected chat UI to read localStorage["${ CHAT_TRANSPORT_MODE_STORAGE_KEY } "] ` +
28+ `and recognize "${ CHAT_TRANSPORT_MODE_WEBSOCKET } ".` ;
29+ const CHAT_TRANSPORT_WRITE_HINT =
30+ `Expected chat UI to persist transport mode via localStorage.setItem("${ CHAT_TRANSPORT_MODE_STORAGE_KEY } ", ...).` ;
31+
132const DESKTOP_BRIDGE_PATTERNS = {
233 trayRestartGuard : / i f \s * \( \s * ! d e s k t o p B r i d g e \s * \? \. \s * o n T r a y R e s t a r t B a c k e n d \s * \) \s * \{ / ,
334 trayRestartPromptInvoke :
@@ -10,6 +41,12 @@ const DESKTOP_BRIDGE_PATTERNS = {
1041 / c o n s t \s + r u n t i m e I n f o \s * = \s * a w a i t \s + g e t D e s k t o p R u n t i m e I n f o \s * \( \s * \) \s * ; ? [ \s \S ] * ?i s D e s k t o p R e l e a s e M o d e \. v a l u e \s * = \s * r u n t i m e I n f o \. i s D e s k t o p R u n t i m e / ,
1142 desktopReleaseModeFlag : / \b i s D e s k t o p R e l e a s e M o d e \b / ,
1243 desktopRuntimeProbeWarn : / c o n s o l e \. w a r n \( [ \s \S ] * d e s k t o p r u n t i m e / i,
44+ chatTransportPreferenceRead : new RegExp (
45+ `localStorage\\.getItem\\(["']${ CHAT_TRANSPORT_STORAGE_KEY_PATTERN } ["']\\)[\\s\\S]*?["']${ CHAT_TRANSPORT_WEBSOCKET_PATTERN } ["']` ,
46+ ) ,
47+ chatTransportPreferenceWrite : new RegExp (
48+ `localStorage\\.setItem\\(["']${ CHAT_TRANSPORT_STORAGE_KEY_PATTERN } ["']\\s*,` ,
49+ ) ,
1350} ;
1451
1552const DESKTOP_BRIDGE_EXPECTATIONS = [
@@ -62,6 +99,27 @@ const DESKTOP_BRIDGE_EXPECTATIONS = [
6299 hint : 'Expected warning log when desktop runtime detection fails.' ,
63100 required : false ,
64101 } ,
102+ {
103+ filePath : [ 'src' , 'components' , 'chat' , 'Chat.vue' ] ,
104+ pattern : DESKTOP_BRIDGE_PATTERNS . chatTransportPreferenceRead ,
105+ label : 'chat transport preference read' ,
106+ hint : CHAT_TRANSPORT_READ_HINT ,
107+ required : true ,
108+ } ,
109+ {
110+ filePath : [ 'src' , 'components' , 'chat' , 'Chat.vue' ] ,
111+ pattern : DESKTOP_BRIDGE_PATTERNS . chatTransportPreferenceWrite ,
112+ label : 'chat transport preference write' ,
113+ hint : CHAT_TRANSPORT_WRITE_HINT ,
114+ required : true ,
115+ } ,
116+ {
117+ filePath : [ 'src' , 'components' , 'chat' , 'StandaloneChat.vue' ] ,
118+ pattern : DESKTOP_BRIDGE_PATTERNS . chatTransportPreferenceRead ,
119+ label : 'standalone chat transport preference read' ,
120+ hint : CHAT_TRANSPORT_READ_HINT ,
121+ required : true ,
122+ } ,
65123] ;
66124
67125export const getDesktopBridgeExpectations = ( ) => [ ...DESKTOP_BRIDGE_EXPECTATIONS ] ;
0 commit comments