1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
|
# Viewer to External Editor JSON-RPC<br>Message Interfaces Documentation
This document describes all the message interfaces defined in for WebSocket communication between the Second Life viewer and an external editor such as a VSCode extension.
## Table of Contents
- [Usage Flow](#usage-flow)
- [JSON-RPC Method Summary](#json-rpc-method-summary)
- [Session Management Interfaces](#session-management-interfaces)
- [SessionHandshake](#sessionhandshake)
- [SessionHandshakeResponse](#sessionhandshakeresponse)
- [Session OK](#session-ok)
- [SessionDisconnect](#sessiondisconnect)
- [Language and Syntax Interfaces](#language-and-syntax-interfaces)
- [SyntaxChange](#syntaxchange)
- [Language Syntax ID Request](#language-syntax-id-request)
- [Language Syntax Request](#language-syntax-request)
- [Script Subscription Interfaces](#script-subscription-interfaces)
- [ScriptSubscribe](#scriptsubscribe)
- [ScriptSubscribeResponse](#scriptsubscriberesponse)
- [ScriptUnsubscribe](#scriptunsubscribe)
- [Compilation Interfaces](#compilation-interfaces)
- [CompilationError](#compilationerror)
- [CompilationResult](#compilationresult)
- [Runtime Event Interfaces](#runtime-event-interfaces)
- [RuntimeDebug](#runtimedebug)
- [RuntimeError](#runtimeerror)
- [Handler and Configuration Interfaces](#handler-and-configuration-interfaces)
- [WebSocketHandlers](#websockethandlers)
- [ClientInfo](#clientinfo)
## Usage Flow
1. **Connection Establishment:**
- Viewer sends `session.handshake` notification with `SessionHandshake` data
- Extension responds with `SessionHandshakeResponse`
- Viewer confirms with `session.ok` notification
2. **Language Information Exchange:**
- Extension makes `language.syntax.id` call to get current syntax version
- Extension makes `language.syntax` calls with different `kind` parameters to get specific language data
- Viewer responds with `LanguageInfo` data containing the requested information
3. **Script Subscription Management:**
- Extension makes `script.subscribe` call with `ScriptSubscribe` data to request live synchronization for a script
- Viewer responds with `ScriptSubscribeResponse` indicating success or failure
- When subscription needs to be terminated, viewer sends `script.unsubscribe` notification with `ScriptUnsubscribe` data
- Extension handles unsubscription by cleaning up local script tracking
4. **Runtime Events:**
- Viewer sends `language.syntax.change` notification with `SyntaxChange` when language changes
- Viewer sends `script.compiled` notification with `CompilationResult` after script compilation
- Viewer sends `runtime.debug` notification with `RuntimeDebug` for debug messages during script execution
- Viewer sends `runtime.error` notification with `RuntimeError` when runtime errors occur
5. **Connection Termination:**
- Either side can send `session.disconnect` notification with `SessionDisconnect` data
- Connection is closed gracefully
## JSON-RPC Method Summary
| Method | Direction | Type | Interface/Parameters |
| ------------------------------- | ------------------ | ------------ | -------------------------- |
| `session.handshake` | Viewer → Extension | Notification | `SessionHandshake` |
| `session.handshake` (response) | Extension → Viewer | Response | `SessionHandshakeResponse` |
| `session.ok` | Viewer → Extension | Notification | _(no interface)_ |
| `session.disconnect` | Bidirectional | Notification | `SessionDisconnect` |
| `script.subscribe` | Extension → Viewer | Call | `ScriptSubscribe` |
| `script.subscribe` (response) | Viewer → Extension | Response | `ScriptSubscribeResponse` |
| `script.unsubscribe` | Viewer → Extension | Notification | `ScriptUnsubscribe` |
| `language.syntax.id` | Extension → Viewer | Call | _(no parameters)_ |
| `language.syntax.id` (response) | Viewer → Extension | Response | `{ id: string }` |
| `language.syntax` | Extension → Viewer | Call | `{ kind: string }` |
| `language.syntax` (response) | Viewer → Extension | Response | `LanguageInfo` |
| `language.syntax.change` | Viewer → Extension | Notification | `SyntaxChange` |
| `script.compiled` | Viewer → Extension | Notification | `CompilationResult` |
| `runtime.debug` | Viewer → Extension | Notification | `RuntimeDebug` |
| `runtime.error` | Viewer → Extension | Notification | `RuntimeError` |
## Session Management Interfaces
### SessionHandshake
**JSON-RPC Method:** `session.handshake` (notification from viewer)
The initial handshake message sent by the viewer to establish a connection.
```typescript
interface SessionHandshake {
server_version: "1.0.0";
protocol_version: "1.0";
viewer_name: string;
viewer_version: string;
agent_id: string;
agent_name: string;
challenge?: string;
languages: string[];
syntax_id: string;
features: { [feature: string]: boolean };
}
```
**Fields:**
- `server_version`: Fixed version "1.0.0" indicating the server API version
- `protocol_version`: Fixed version "1.0" for the communication protocol
- `viewer_name`: Name of the Second Life viewer application
- `viewer_version`: Version string of the viewer
- `agent_id`: Unique identifier for the user/agent
- `agent_name`: Human-readable name of the agent
- `challenge` (optional): Security challenge string for authentication
- `languages`: Array of supported scripting languages (e.g., ["lsl", "luau"])
- `syntax_id`: Current active syntax/language identifier
- `features`: Dictionary of feature flags indicating viewer capabilities
### SessionHandshakeResponse
**JSON-RPC Method:** Response to `session.handshake`
The response sent by the VS Code extension to complete the handshake.
```typescript
interface SessionHandshakeResponse {
client_name: string;
client_version: "1.0";
protocol_version: string;
challenge_response?: string;
languages: string[];
features: { [feature: string]: boolean };
}
```
**Fields:**
- `client_name`: Name of the client (VS Code extension)
- `client_version`: Fixed version "1.0" of the client
- `protocol_version`: Protocol version the client supports
- `challenge_response` (optional): Response to the security challenge if provided
- `languages`: Array of languages supported by the client
- `features`: Dictionary of features supported by the client
### Session OK
**JSON-RPC Method:** `session.ok` (notification from viewer)
Confirmation notification sent by the viewer after successful handshake completion. This interface has no defined structure as it appears to be a simple confirmation message.
### SessionDisconnect
**JSON-RPC Method:** `session.disconnect` (notification, bidirectional)
Message sent when terminating the connection.
```typescript
interface SessionDisconnect {
reason: number;
message: string;
}
```
**Fields:**
- `reason`: Numeric code indicating the reason for disconnection
- `message`: Human-readable description of the disconnect reason
## Language and Syntax Interfaces
### SyntaxChange
**JSON-RPC Method:** `language.syntax.change` (notification from viewer)
Notification sent when the active language syntax changes in the viewer.
```typescript
interface SyntaxChange {
id: string;
}
```
**Fields:**
- `id`: Identifier for the new syntax/language
### Language Syntax ID Request
**JSON-RPC Method:** `language.syntax.id` (call from extension to viewer)
Requests the current active language syntax identifier from the viewer. This method takes no parameters.
**Response:** Returns an object with an `id` field containing the current syntax identifier.
### Language Syntax Request
**JSON-RPC Method:** `language.syntax` (call from extension to viewer)
Requests detailed syntax information for a specific language kind.
**Parameters:**
```typescript
{
kind: string; // The type of syntax information requested
}
```
**Fields:**
- `kind`: The type of syntax information to retrieve (e.g., "functions", "constants", "events", "types.luau")
**Response:** Returns `LanguageInfo` data containing the requested syntax information:
```typescript
interface LanguageInfo {
id: string;
lslDefs?: {
controls?: any;
types?: any;
constants?: { [name: string]: ConstantDef };
events?: { [name: string]: FunctionDef };
functions?: { [name: string]: FunctionDef };
};
luaDefs?: {
modules?: { [name: string]: TypeDef };
classes?: { [name: string]: TypeDef };
aliases?: { [name: string]: TypeDef };
functions?: { [name: string]: FunctionDef };
};
}
```
**Response Fields:**
- `id`: Version identifier for the language syntax
- `lslDefs` (optional): LSL-specific language definitions containing:
- `controls` (optional): Control flow and language constructs
- `types` (optional): LSL type definitions
- `constants` (optional): Object containing constant definitions keyed by constant name
- `events` (optional): Object containing event definitions keyed by event name
- `functions` (optional): Object containing function definitions keyed by function name
- `luaDefs` (optional): Lua-specific language definitions containing:
- `modules` (optional): Module type definitions keyed by module name
- `classes` (optional): Class type definitions keyed by class name
- `aliases` (optional): Type alias definitions keyed by alias name
- `functions` (optional): Function definitions keyed by function name
The specific sections returned depend on the `kind` parameter and the active language context.
## Script Subscription Interfaces
### ScriptSubscribe
**JSON-RPC Method:** `script.subscribe` (call from extension to viewer)
Requests subscription to a script for live synchronization between the editor and viewer.
```typescript
interface ScriptSubscribe {
script_id: string;
script_name: string;
script_language: string;
}
```
**Fields:**
- `script_id`: Unique identifier for the script to subscribe to
- `script_name`: Display name of the script file
- `script_language`: Programming language of the script (e.g., "lsl", "luau")
### ScriptSubscribeResponse
**JSON-RPC Method:** Response to `script.subscribe`
Response from the viewer indicating whether script subscription was successful.
```typescript
interface ScriptSubscribeResponse {
script_id: string;
success: boolean;
status: number;
object_id?: string;
object_name?: string;
item_id?: string;
message?: string;
}
```
**Fields:**
- `script_id`: The script identifier that was subscribed to
- `success`: Whether the subscription was successful
- `status`: Numeric status code indicating the result
- `object_id` (optional): The in-world ID of the object containing the script
- `object_name` (optional): The name of the object containing the script.
- `message` (optional): Additional information about the subscription result
### ScriptUnsubscribe
**JSON-RPC Method:** `script.unsubscribe` (notification from viewer)
Notification sent by the viewer when a script subscription should be terminated.
```typescript
interface ScriptUnsubscribe {
script_id: string;
}
```
**Fields:**
- `script_id`: Unique identifier for the script to unsubscribe from
## Compilation Interfaces
### CompilationError
Individual compilation error record.
```typescript
interface CompilationError {
row: number;
column: number;
level: "ERROR";
message: string;
}
```
**Fields:**
- `row`: Line number where the error occurred (0-based or 1-based depending on context)
- `column`: Column position of the error
- `level`: Severity level (currently only "ERROR" is defined)
- `message`: Error description
### CompilationResult
**JSON-RPC Method:** `script.compiled` (notification from viewer)
Result of a compilation operation in the viewer.
```typescript
interface CompilationResult {
script_id: string;
success: boolean;
running: boolean;
errors?: CompilationError[];
}
```
**Fields:**
- `script_id`: Unique identifier for the script that was compiled
- `success`: Whether the compilation was successful
- `running`: Whether the compiled script is currently running
- `errors` (optional): Array of compilation errors if any occurred
## Runtime Event Interfaces
### RuntimeDebug
**JSON-RPC Method:** `runtime.debug` (notification from viewer)
Debug message notification sent by the viewer during script execution.
```typescript
interface RuntimeDebug {
script_id: string;
object_id: string;
object_name: string;
message: string;
}
```
**Fields:**
- `script_id`: Unique identifier for the script generating the debug message
- `object_id`: Unique identifier for the object containing the script
- `object_name`: Human-readable name of the object
- `message`: The debug message content
### RuntimeError
**JSON-RPC Method:** `runtime.error` (notification from viewer)
Runtime error notification sent by the viewer when a script encounters an error during execution.
```typescript
interface RuntimeError {
script_id: string;
object_id: string;
object_name: string;
message: string;
error: string;
line: number;
stack?: string[];
}
```
**Fields:**
- `script_id`: Unique identifier for the script that encountered the error
- `object_id`: Unique identifier for the object containing the script
- `object_name`: Human-readable name of the object
- `message`: Error message description
- `error`: Specific error type or code
- `line`: Line number where the error occurred
- `stack` (optional): Stack trace information if available
## Handler and Configuration Interfaces
### WebSocketHandlers
Event handler interface for WebSocket events.
```typescript
interface WebSocketHandlers {
onHandshake?: (message: SessionHandshake) => SessionHandshakeResponse;
onHandshakeOk?: () => void;
onDisconnect?: (message: SessionDisconnect) => void;
onSubscribe?: (message: ScriptSubscribe) => ScriptSubscribeResponse;
onUnsubscribe?: (message: ScriptUnsubscribe) => void;
onSyntaxChange?: (message: SyntaxChange) => void;
onConnectionClosed?: () => void;
onCompilationResult?: (message: CompilationResult) => void;
onRuntimeDebug?: (message: RuntimeDebug) => void;
onRuntimeError?: (message: RuntimeError) => void;
}
```
**Methods:**
- `onHandshake`: Handler for initial handshake message, returns handshake response
- `onHandshakeOk`: Handler called when handshake is successfully completed
- `onDisconnect`: Handler for disconnect notifications
- `onSubscribe`: Handler for script subscription requests from viewer, returns subscription response
- `onUnsubscribe`: Handler for script unsubscription notifications from viewer
- `onSyntaxChange`: Handler for syntax change notifications
- `onConnectionClosed`: Handler called when connection is closed
- `onCompilationResult`: Handler for compilation result notifications
- `onRuntimeDebug`: Handler for runtime debug message notifications
- `onRuntimeError`: Handler for runtime error notifications
### ClientInfo
Client information used in handshake responses.
```typescript
interface ClientInfo {
scriptName: string;
scriptId: string;
extension: string;
}
```
**Fields:**
- `scriptName`: Name of the script being edited
- `scriptId`: Unique identifier for the script
- `extension`: File extension or script type
|