ropilot 0.1.10 → 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 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(`Content-Length: ${Buffer.byteLength(json)}\r\n\r\n${json}`);
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
- if (contentLength === -1) {
175
- const headerEnd = buffer.indexOf('\r\n\r\n');
176
- if (headerEnd === -1) break;
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
- // We have Content-Length, wait for body
204
- if (buffer.length >= contentLength) {
205
- const body = buffer.slice(0, contentLength);
206
- buffer = buffer.slice(contentLength);
207
- contentLength = -1;
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(body);
214
+ const request = JSON.parse(line);
211
215
  handleRequest(apiKey, request);
212
216
  } catch (e) {
213
- sendError(null, -32700, 'Parse error');
217
+ // Invalid JSON, skip this line
214
218
  }
215
- } else {
216
- break;
217
219
  }
218
220
  }
219
221
  });
package/lib/setup.js CHANGED
@@ -237,45 +237,6 @@ function installGlobally() {
237
237
  }
238
238
  }
239
239
 
240
- /**
241
- * Create .mcp.json for Claude Code compatibility
242
- */
243
- function createMcpConfig(useNpx = false) {
244
- const mcpConfig = {
245
- mcpServers: {
246
- ropilot: useNpx ? {
247
- command: "npx",
248
- args: ["ropilot", "serve"]
249
- } : {
250
- command: "ropilot",
251
- args: ["serve"]
252
- }
253
- }
254
- };
255
-
256
- const mcpPath = '.mcp.json';
257
-
258
- if (existsSync(mcpPath)) {
259
- // Merge with existing config
260
- try {
261
- const existing = JSON.parse(readFileSync(mcpPath, 'utf-8'));
262
- if (!existing.mcpServers?.ropilot) {
263
- existing.mcpServers = existing.mcpServers || {};
264
- existing.mcpServers.ropilot = mcpConfig.mcpServers.ropilot;
265
- writeFileSync(mcpPath, JSON.stringify(existing, null, 2));
266
- console.log(` Updated: ${mcpPath} (added ropilot server)`);
267
- } else {
268
- console.log(` Exists: ${mcpPath} (ropilot already configured)`);
269
- }
270
- } catch (err) {
271
- console.error(` Failed to update ${mcpPath}: ${err.message}`);
272
- }
273
- } else {
274
- writeFileSync(mcpPath, JSON.stringify(mcpConfig, null, 2));
275
- console.log(` Created: ${mcpPath}`);
276
- }
277
- }
278
-
279
240
  /**
280
241
  * Download prompts from edge server
281
242
  */
@@ -459,10 +420,9 @@ export async function init(providedApiKey = null) {
459
420
  const pkg = await downloadPrompts(apiKey);
460
421
  console.log('');
461
422
 
462
- // Set up project files
423
+ // Set up project files (includes .mcp.json from package)
463
424
  console.log('Setting up project files...');
464
425
  setupProjectPrompts(pkg);
465
- createMcpConfig(!globalInstallOk);
466
426
  console.log('');
467
427
 
468
428
  // Done!
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ropilot",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "description": "AI-powered Roblox development assistant - MCP CLI",
5
5
  "author": "whut",
6
6
  "license": "MIT",