ropilot 0.1.11 → 0.1.12
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.
- package/bin/ropilot.js +0 -0
- package/lib/proxy.js +33 -31
- package/package.json +1 -1
package/bin/ropilot.js
CHANGED
|
File without changes
|
package/lib/proxy.js
CHANGED
|
@@ -15,11 +15,11 @@ const PLUGIN_VERSION_URL = 'https://ropilot.ai/plugin/version';
|
|
|
15
15
|
const PLUGIN_DOWNLOAD_URL = 'https://ropilot.ai/plugin/StudioPlugin.lua';
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
|
-
* Send JSON-RPC response to stdout
|
|
18
|
+
* Send JSON-RPC response to stdout (newline-delimited JSON)
|
|
19
19
|
*/
|
|
20
20
|
function sendResponse(response) {
|
|
21
21
|
const json = JSON.stringify(response);
|
|
22
|
-
process.stdout.write(
|
|
22
|
+
process.stdout.write(json + '\n');
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
/**
|
|
@@ -163,57 +163,59 @@ export async function serve() {
|
|
|
163
163
|
checkPluginUpdate();
|
|
164
164
|
|
|
165
165
|
// Read JSON-RPC messages from stdin
|
|
166
|
+
// Supports both Content-Length framing (LSP-style) and newline-delimited JSON
|
|
166
167
|
let buffer = '';
|
|
167
168
|
let contentLength = -1;
|
|
168
169
|
|
|
169
170
|
process.stdin.on('data', (chunk) => {
|
|
170
171
|
buffer += chunk.toString();
|
|
171
172
|
|
|
172
|
-
// Try to parse Content-Length header
|
|
173
173
|
while (true) {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
if (
|
|
174
|
+
// If we're waiting for a body with known Content-Length
|
|
175
|
+
if (contentLength > 0) {
|
|
176
|
+
if (buffer.length >= contentLength) {
|
|
177
|
+
const body = buffer.slice(0, contentLength);
|
|
178
|
+
buffer = buffer.slice(contentLength);
|
|
179
|
+
contentLength = -1;
|
|
177
180
|
|
|
181
|
+
try {
|
|
182
|
+
const request = JSON.parse(body);
|
|
183
|
+
handleRequest(apiKey, request);
|
|
184
|
+
} catch (e) {
|
|
185
|
+
sendError(null, -32700, 'Parse error');
|
|
186
|
+
}
|
|
187
|
+
continue;
|
|
188
|
+
} else {
|
|
189
|
+
break; // Wait for more data
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Check for Content-Length header (LSP-style framing)
|
|
194
|
+
const headerEnd = buffer.indexOf('\r\n\r\n');
|
|
195
|
+
if (headerEnd !== -1) {
|
|
178
196
|
const header = buffer.slice(0, headerEnd);
|
|
179
197
|
const match = header.match(/Content-Length: (\d+)/i);
|
|
180
198
|
if (match) {
|
|
181
199
|
contentLength = parseInt(match[1], 10);
|
|
182
200
|
buffer = buffer.slice(headerEnd + 4);
|
|
183
|
-
} else {
|
|
184
|
-
// No Content-Length, try to parse as raw JSON
|
|
185
|
-
try {
|
|
186
|
-
const lineEnd = buffer.indexOf('\n');
|
|
187
|
-
if (lineEnd === -1) break;
|
|
188
|
-
|
|
189
|
-
const line = buffer.slice(0, lineEnd).trim();
|
|
190
|
-
buffer = buffer.slice(lineEnd + 1);
|
|
191
|
-
|
|
192
|
-
if (line) {
|
|
193
|
-
const request = JSON.parse(line);
|
|
194
|
-
handleRequest(apiKey, request);
|
|
195
|
-
}
|
|
196
|
-
} catch (e) {
|
|
197
|
-
buffer = buffer.slice(buffer.indexOf('\n') + 1);
|
|
198
|
-
}
|
|
199
201
|
continue;
|
|
200
202
|
}
|
|
201
203
|
}
|
|
202
204
|
|
|
203
|
-
//
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
205
|
+
// No Content-Length header - try newline-delimited JSON
|
|
206
|
+
const lineEnd = buffer.indexOf('\n');
|
|
207
|
+
if (lineEnd === -1) break; // Wait for complete line
|
|
208
|
+
|
|
209
|
+
const line = buffer.slice(0, lineEnd).trim();
|
|
210
|
+
buffer = buffer.slice(lineEnd + 1);
|
|
208
211
|
|
|
212
|
+
if (line && line.startsWith('{')) {
|
|
209
213
|
try {
|
|
210
|
-
const request = JSON.parse(
|
|
214
|
+
const request = JSON.parse(line);
|
|
211
215
|
handleRequest(apiKey, request);
|
|
212
216
|
} catch (e) {
|
|
213
|
-
|
|
217
|
+
// Invalid JSON, skip this line
|
|
214
218
|
}
|
|
215
|
-
} else {
|
|
216
|
-
break;
|
|
217
219
|
}
|
|
218
220
|
}
|
|
219
221
|
});
|