rbxstudio-mcp 1.9.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/LICENSE +21 -0
  2. package/README.md +319 -0
  3. package/dist/__tests__/bridge-service.test.d.ts +2 -0
  4. package/dist/__tests__/bridge-service.test.d.ts.map +1 -0
  5. package/dist/__tests__/bridge-service.test.js +109 -0
  6. package/dist/__tests__/bridge-service.test.js.map +1 -0
  7. package/dist/__tests__/http-server.test.d.ts +2 -0
  8. package/dist/__tests__/http-server.test.d.ts.map +1 -0
  9. package/dist/__tests__/http-server.test.js +193 -0
  10. package/dist/__tests__/http-server.test.js.map +1 -0
  11. package/dist/__tests__/integration.test.d.ts +2 -0
  12. package/dist/__tests__/integration.test.d.ts.map +1 -0
  13. package/dist/__tests__/integration.test.js +182 -0
  14. package/dist/__tests__/integration.test.js.map +1 -0
  15. package/dist/__tests__/smoke.test.d.ts +2 -0
  16. package/dist/__tests__/smoke.test.d.ts.map +1 -0
  17. package/dist/__tests__/smoke.test.js +63 -0
  18. package/dist/__tests__/smoke.test.js.map +1 -0
  19. package/dist/bridge-service.d.ts +17 -0
  20. package/dist/bridge-service.d.ts.map +1 -0
  21. package/dist/bridge-service.js +77 -0
  22. package/dist/bridge-service.js.map +1 -0
  23. package/dist/http-server.d.ts +4 -0
  24. package/dist/http-server.d.ts.map +1 -0
  25. package/dist/http-server.js +290 -0
  26. package/dist/http-server.js.map +1 -0
  27. package/dist/index.d.ts +18 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +1102 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/tools/index.d.ts +273 -0
  32. package/dist/tools/index.d.ts.map +1 -0
  33. package/dist/tools/index.js +628 -0
  34. package/dist/tools/index.js.map +1 -0
  35. package/dist/tools/studio-client.d.ts +7 -0
  36. package/dist/tools/studio-client.d.ts.map +1 -0
  37. package/dist/tools/studio-client.js +19 -0
  38. package/dist/tools/studio-client.js.map +1 -0
  39. package/package.json +69 -0
  40. package/studio-plugin/INSTALLATION.md +150 -0
  41. package/studio-plugin/MCPPlugin.rbxmx +3253 -0
  42. package/studio-plugin/plugin.json +10 -0
  43. package/studio-plugin/plugin.luau +3584 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-server.test.js","sourceRoot":"","sources":["../../src/__tests__/http-server.test.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,WAAW,CAAC;AAChC,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGlD,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,IAAI,GAAsB,CAAC;IAC3B,IAAI,MAAqB,CAAC;IAC1B,IAAI,KAAwB,CAAC;IAE7B,UAAU,CAAC,GAAG,EAAE;QACd,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;QAC7B,KAAK,GAAG,IAAI,iBAAiB,CAAC,MAAM,CAAC,CAAC;QACtC,GAAG,GAAG,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;QAC5B,IAAI,CAAC,6BAA6B,EAAE,KAAK,IAAI,EAAE;YAC7C,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;iBAChC,GAAG,CAAC,SAAS,CAAC;iBACd,MAAM,CAAC,GAAG,CAAC,CAAC;YAEf,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,aAAa,CAAC;gBAClC,MAAM,EAAE,IAAI;gBACZ,OAAO,EAAE,kBAAkB;gBAC3B,eAAe,EAAE,KAAK;gBACtB,eAAe,EAAE,KAAK;aACvB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,8BAA8B,EAAE,GAAG,EAAE;QAC5C,IAAI,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;YACzD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;iBAChC,IAAI,CAAC,QAAQ,CAAC;iBACd,MAAM,CAAC,GAAG,CAAC,CAAC;YAEf,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YACjD,MAAM,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;YACjD,gBAAgB;YAChB,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC9C,MAAM,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAE3C,kBAAkB;YAClB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;iBAChC,IAAI,CAAC,aAAa,CAAC;iBACnB,MAAM,CAAC,GAAG,CAAC,CAAC;YAEf,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YACjD,MAAM,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;YAC7D,4BAA4B;YAC5B,MAAM,CAAC,WAAW,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;YACrC,MAAM,CAAC,WAAW,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;YAErC,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC;YAEhD,aAAa;YACb,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAEnD,iCAAiC;YACjC,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;QAChD,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;YACnE,iBAAiB;YACjB,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC9C,MAAM,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAE3C,mDAAmD;YACnD,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC;YACjC,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,eAAe,EAAE,GAAG,KAAK,CAAC,CAAC;YAEpD,2CAA2C;YAC3C,MAAM,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAE5C,mBAAmB;YACnB,IAAI,CAAC,GAAG,GAAG,eAAe,CAAC;QAC7B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAChC,IAAI,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;YACjE,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;iBAChC,GAAG,CAAC,OAAO,CAAC;iBACZ,MAAM,CAAC,GAAG,CAAC,CAAC;YAEf,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,aAAa,CAAC;gBAClC,KAAK,EAAE,0BAA0B;gBACjC,eAAe,EAAE,IAAI;gBACrB,YAAY,EAAE,KAAK;gBACnB,OAAO,EAAE,IAAI;aACd,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;YAClE,sBAAsB;YACtB,GAAG,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;YAE7B,wBAAwB;YACxB,MAAM,CAAC,WAAW,CAAC,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;YAElD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;iBAChC,GAAG,CAAC,OAAO,CAAC;iBACZ,MAAM,CAAC,GAAG,CAAC,CAAC;YAEf,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,aAAa,CAAC;gBAClC,OAAO,EAAE;oBACP,QAAQ,EAAE,WAAW;oBACrB,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;iBACvB;gBACD,YAAY,EAAE,IAAI;gBAClB,eAAe,EAAE,IAAI;aACtB,CAAC,CAAC;YACH,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,UAAU,EAAE,CAAC;QAC/C,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;YACrE,sBAAsB;YACtB,GAAG,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;YAE7B,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;iBAChC,GAAG,CAAC,OAAO,CAAC;iBACZ,MAAM,CAAC,GAAG,CAAC,CAAC;YAEf,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,aAAa,CAAC;gBAClC,OAAO,EAAE,IAAI;gBACb,YAAY,EAAE,IAAI;gBAClB,eAAe,EAAE,IAAI;aACtB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;YAC9D,MAAM,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAE5C,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAE5C,MAAM,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;QACjC,IAAI,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;YACnD,MAAM,SAAS,GAAG,iBAAiB,CAAC;YACpC,MAAM,YAAY,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;YAE3C,2BAA2B;YAC3B,MAAM,cAAc,GAAG,MAAM,CAAC,WAAW,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;YAC3D,MAAM,cAAc,GAAG,MAAM,CAAC,iBAAiB,EAAE,CAAC;YAElD,gBAAgB;YAChB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;iBAChC,IAAI,CAAC,WAAW,CAAC;iBACjB,IAAI,CAAC;gBACJ,SAAS,EAAE,cAAe,CAAC,SAAS;gBACpC,QAAQ,EAAE,YAAY;aACvB,CAAC;iBACD,MAAM,CAAC,GAAG,CAAC,CAAC;YAEf,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YAEjD,sCAAsC;YACtC,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC;YACpC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;YAC9C,MAAM,KAAK,GAAG,oBAAoB,CAAC;YAEnC,2BAA2B;YAC3B,MAAM,cAAc,GAAG,MAAM,CAAC,WAAW,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;YAC3D,MAAM,cAAc,GAAG,MAAM,CAAC,iBAAiB,EAAE,CAAC;YAElD,sBAAsB;YACtB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;iBAChC,IAAI,CAAC,WAAW,CAAC;iBACjB,IAAI,CAAC;gBACJ,SAAS,EAAE,cAAe,CAAC,SAAS;gBACpC,KAAK,EAAE,KAAK;aACb,CAAC;iBACD,MAAM,CAAC,GAAG,CAAC,CAAC;YAEf,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YAEjD,sCAAsC;YACtC,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;QAC3C,IAAI,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;YAClD,GAAG,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;YAC7B,MAAM,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAE3C,oBAAoB;YACpB,GAAG,CAAC,gBAAgB,EAAE,CAAC;YAEvB,yBAAyB;YACzB,MAAM,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;YAC5D,GAAG,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;YAC7B,MAAM,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAE3C,mDAAmD;YACnD,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC;YACjC,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,eAAe,EAAE,GAAG,KAAK,CAAC,CAAC;YAEpD,2CAA2C;YAC3C,MAAM,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAE5C,mBAAmB;YACnB,IAAI,CAAC,GAAG,GAAG,eAAe,CAAC;QAC7B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;QAC/B,IAAI,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;YAC9C,oBAAoB;YACpB,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC9C,GAAG,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;YAE7B,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;iBAChC,GAAG,CAAC,SAAS,CAAC;iBACd,MAAM,CAAC,GAAG,CAAC,CAAC;YAEf,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,aAAa,CAAC;gBAClC,eAAe,EAAE,IAAI;gBACrB,eAAe,EAAE,IAAI;aACtB,CAAC,CAAC;YACH,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;YACzD,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=integration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/integration.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,182 @@
1
+ import request from 'supertest';
2
+ import { createHttpServer } from '../http-server';
3
+ import { RobloxStudioTools } from '../tools/index';
4
+ import { BridgeService } from '../bridge-service';
5
+ describe('Integration Tests', () => {
6
+ let app;
7
+ let bridge;
8
+ let tools;
9
+ beforeEach(() => {
10
+ bridge = new BridgeService();
11
+ tools = new RobloxStudioTools(bridge);
12
+ app = createHttpServer(tools, bridge);
13
+ });
14
+ describe('Full Connection Flow', () => {
15
+ test('should handle complete connection lifecycle', async () => {
16
+ // 1. Initial state - nothing connected
17
+ let status = await request(app).get('/status').expect(200);
18
+ expect(status.body.pluginConnected).toBe(false);
19
+ expect(status.body.mcpServerActive).toBe(false);
20
+ // 2. Plugin connects
21
+ await request(app).post('/ready').expect(200);
22
+ status = await request(app).get('/status').expect(200);
23
+ expect(status.body.pluginConnected).toBe(true);
24
+ expect(status.body.mcpServerActive).toBe(false);
25
+ // 3. Plugin polls - should show MCP not connected
26
+ let pollResponse = await request(app).get('/poll').expect(503);
27
+ expect(pollResponse.body).toMatchObject({
28
+ error: 'MCP server not connected',
29
+ pluginConnected: true,
30
+ mcpConnected: false
31
+ });
32
+ // 4. MCP server activates
33
+ app.setMCPServerActive(true);
34
+ status = await request(app).get('/status').expect(200);
35
+ expect(status.body.pluginConnected).toBe(true);
36
+ expect(status.body.mcpServerActive).toBe(true);
37
+ // 5. Plugin polls - should show both connected
38
+ pollResponse = await request(app).get('/poll').expect(200);
39
+ expect(pollResponse.body).toMatchObject({
40
+ request: null,
41
+ mcpConnected: true,
42
+ pluginConnected: true
43
+ });
44
+ // 6. Plugin disconnects
45
+ await request(app).post('/disconnect').expect(200);
46
+ status = await request(app).get('/status').expect(200);
47
+ expect(status.body.pluginConnected).toBe(false);
48
+ expect(status.body.mcpServerActive).toBe(true); // MCP still active
49
+ });
50
+ });
51
+ describe('Request/Response Flow', () => {
52
+ test('should handle complete request/response cycle', async () => {
53
+ // Setup: Connect everything
54
+ await request(app).post('/ready').expect(200);
55
+ app.setMCPServerActive(true);
56
+ // 1. MCP sends a request through bridge
57
+ const mcpRequestPromise = bridge.sendRequest('/api/test-endpoint', {
58
+ testData: 'hello',
59
+ value: 123
60
+ });
61
+ // 2. Plugin polls and gets the request
62
+ const pollResponse = await request(app).get('/poll').expect(200);
63
+ expect(pollResponse.body.request).toMatchObject({
64
+ endpoint: '/api/test-endpoint',
65
+ data: {
66
+ testData: 'hello',
67
+ value: 123
68
+ }
69
+ });
70
+ const requestId = pollResponse.body.requestId;
71
+ // 3. Plugin processes and sends response
72
+ await request(app)
73
+ .post('/response')
74
+ .send({
75
+ requestId: requestId,
76
+ response: {
77
+ success: true,
78
+ result: 'processed',
79
+ echo: 'hello'
80
+ }
81
+ })
82
+ .expect(200);
83
+ // 4. MCP receives the response
84
+ const mcpResponse = await mcpRequestPromise;
85
+ expect(mcpResponse).toEqual({
86
+ success: true,
87
+ result: 'processed',
88
+ echo: 'hello'
89
+ });
90
+ });
91
+ test('should handle error responses', async () => {
92
+ // Setup
93
+ await request(app).post('/ready').expect(200);
94
+ app.setMCPServerActive(true);
95
+ // Send request
96
+ const mcpRequestPromise = bridge.sendRequest('/api/failing-endpoint', {});
97
+ // Poll for request
98
+ const pollResponse = await request(app).get('/poll').expect(200);
99
+ const requestId = pollResponse.body.requestId;
100
+ // Send error response
101
+ await request(app)
102
+ .post('/response')
103
+ .send({
104
+ requestId: requestId,
105
+ error: 'Operation failed: Invalid input'
106
+ })
107
+ .expect(200);
108
+ // Should reject with the error
109
+ await expect(mcpRequestPromise).rejects.toEqual('Operation failed: Invalid input');
110
+ });
111
+ });
112
+ describe('Disconnect Recovery', () => {
113
+ test('should handle disconnect and reconnect gracefully', async () => {
114
+ // Initial connection
115
+ await request(app).post('/ready').expect(200);
116
+ app.setMCPServerActive(true);
117
+ // Create some pending requests
118
+ const request1 = bridge.sendRequest('/api/test1', {});
119
+ const request2 = bridge.sendRequest('/api/test2', {});
120
+ // Verify requests are pending
121
+ let poll = await request(app).get('/poll').expect(200);
122
+ expect(poll.body.request).toBeTruthy();
123
+ // Disconnect
124
+ await request(app).post('/disconnect').expect(200);
125
+ // Requests should be rejected
126
+ await expect(request1).rejects.toThrow('Connection closed');
127
+ await expect(request2).rejects.toThrow('Connection closed');
128
+ // Reconnect
129
+ await request(app).post('/ready').expect(200);
130
+ // Should be able to handle new requests
131
+ const newRequestPromise = bridge.sendRequest('/api/test3', {});
132
+ poll = await request(app).get('/poll').expect(200);
133
+ expect(poll.body.request?.endpoint).toBe('/api/test3');
134
+ // Complete the new request
135
+ await request(app)
136
+ .post('/response')
137
+ .send({
138
+ requestId: poll.body.requestId,
139
+ response: { success: true }
140
+ })
141
+ .expect(200);
142
+ const result = await newRequestPromise;
143
+ expect(result).toEqual({ success: true });
144
+ });
145
+ });
146
+ describe('Connection State Display', () => {
147
+ test('should show correct pending states during connection', async () => {
148
+ // Initially disconnected: "HTTP: X MCP: X"
149
+ let health = await request(app).get('/health').expect(200);
150
+ expect(health.body.pluginConnected).toBe(false);
151
+ expect(health.body.mcpServerActive).toBe(false);
152
+ // Plugin starts polling: "HTTP: ... MCP: ..."
153
+ await request(app).get('/poll').expect(503);
154
+ health = await request(app).get('/health').expect(200);
155
+ expect(health.body.pluginConnected).toBe(true);
156
+ expect(health.body.mcpServerActive).toBe(false);
157
+ // MCP connects: "HTTP: OK MCP: OK"
158
+ app.setMCPServerActive(true);
159
+ const poll = await request(app).get('/poll').expect(200);
160
+ expect(poll.body.mcpConnected).toBe(true);
161
+ expect(poll.body.pluginConnected).toBe(true);
162
+ });
163
+ });
164
+ describe('Timeout Handling', () => {
165
+ test('should handle request timeouts', async () => {
166
+ jest.useFakeTimers();
167
+ // Setup
168
+ await request(app).post('/ready').expect(200);
169
+ app.setMCPServerActive(true);
170
+ // Send request but don't respond
171
+ const timeoutPromise = bridge.sendRequest('/api/slow-endpoint', {});
172
+ // Plugin polls for it
173
+ await request(app).get('/poll').expect(200);
174
+ // Fast forward time past timeout
175
+ jest.advanceTimersByTime(31000);
176
+ // Request should timeout
177
+ await expect(timeoutPromise).rejects.toThrow('Request timeout');
178
+ jest.useRealTimers();
179
+ });
180
+ });
181
+ });
182
+ //# sourceMappingURL=integration.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration.test.js","sourceRoot":"","sources":["../../src/__tests__/integration.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=smoke.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smoke.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/smoke.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,63 @@
1
+ import { BridgeService } from '../bridge-service.js';
2
+ import { createHttpServer } from '../http-server.js';
3
+ import { RobloxStudioTools } from '../tools/index.js';
4
+ import request from 'supertest';
5
+ describe('Smoke Tests - Connection Fixes', () => {
6
+ test('BridgeService should be instantiable', () => {
7
+ const bridge = new BridgeService();
8
+ expect(bridge).toBeDefined();
9
+ expect(bridge.getPendingRequest()).toBeNull();
10
+ });
11
+ test('HTTP server should start and respond to health check', async () => {
12
+ const bridge = new BridgeService();
13
+ const tools = new RobloxStudioTools(bridge);
14
+ const app = createHttpServer(tools, bridge);
15
+ const response = await request(app)
16
+ .get('/health')
17
+ .expect(200);
18
+ expect(response.body.status).toBe('ok');
19
+ expect(response.body.service).toBe('robloxstudio-mcp');
20
+ });
21
+ test('clearAllPendingRequests should clear all requests', async () => {
22
+ const bridge = new BridgeService();
23
+ // Don't wait for these promises - they'll be rejected
24
+ const promise1 = bridge.sendRequest('/test1', {});
25
+ const promise2 = bridge.sendRequest('/test2', {});
26
+ // Should have pending requests
27
+ expect(bridge.getPendingRequest()).toBeTruthy();
28
+ // Clear all requests
29
+ bridge.clearAllPendingRequests();
30
+ // Should have no pending requests
31
+ expect(bridge.getPendingRequest()).toBeNull();
32
+ // Promises should reject
33
+ await expect(promise1).rejects.toThrow('Connection closed');
34
+ await expect(promise2).rejects.toThrow('Connection closed');
35
+ });
36
+ test('Disconnect endpoint should clear pending requests', async () => {
37
+ const bridge = new BridgeService();
38
+ const tools = new RobloxStudioTools(bridge);
39
+ const app = createHttpServer(tools, bridge);
40
+ // Add a pending request (don't await it)
41
+ const pendingPromise = bridge.sendRequest('/test', { data: 'test' });
42
+ // Disconnect should clear it
43
+ await request(app)
44
+ .post('/disconnect')
45
+ .expect(200);
46
+ // Request should be rejected
47
+ await expect(pendingPromise).rejects.toThrow('Connection closed');
48
+ });
49
+ test('Connection states should update correctly', async () => {
50
+ const bridge = new BridgeService();
51
+ const tools = new RobloxStudioTools(bridge);
52
+ const app = createHttpServer(tools, bridge);
53
+ // Initially not connected
54
+ expect(app.isPluginConnected()).toBe(false);
55
+ // After ready
56
+ await request(app).post('/ready').expect(200);
57
+ expect(app.isPluginConnected()).toBe(true);
58
+ // After disconnect
59
+ await request(app).post('/disconnect').expect(200);
60
+ expect(app.isPluginConnected()).toBe(false);
61
+ });
62
+ });
63
+ //# sourceMappingURL=smoke.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smoke.test.js","sourceRoot":"","sources":["../../src/__tests__/smoke.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,OAAO,MAAM,WAAW,CAAC;AAEhC,QAAQ,CAAC,gCAAgC,EAAE,GAAG,EAAE;IAC9C,IAAI,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAChD,MAAM,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;QACnC,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;QAC7B,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;QACtE,MAAM,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,IAAI,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,GAAG,GAAG,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAE5C,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;aAChC,GAAG,CAAC,SAAS,CAAC;aACd,MAAM,CAAC,GAAG,CAAC,CAAC;QAEf,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QACnE,MAAM,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;QAEnC,sDAAsD;QACtD,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAClD,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAElD,+BAA+B;QAC/B,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC;QAEhD,qBAAqB;QACrB,MAAM,CAAC,uBAAuB,EAAE,CAAC;QAEjC,kCAAkC;QAClC,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;QAE9C,yBAAyB;QACzB,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;QAC5D,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QACnE,MAAM,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,IAAI,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,GAAG,GAAG,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAE5C,yCAAyC;QACzC,MAAM,cAAc,GAAG,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QAErE,6BAA6B;QAC7B,MAAM,OAAO,CAAC,GAAG,CAAC;aACf,IAAI,CAAC,aAAa,CAAC;aACnB,MAAM,CAAC,GAAG,CAAC,CAAC;QAEf,6BAA6B;QAC7B,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;QAC3D,MAAM,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,IAAI,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,GAAG,GAAG,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAQ,CAAC;QAEnD,0BAA0B;QAC1B,MAAM,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAE5C,cAAc;QACd,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC9C,MAAM,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAE3C,mBAAmB;QACnB,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACnD,MAAM,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,17 @@
1
+ export declare class BridgeService {
2
+ private pendingRequests;
3
+ private requestTimeout;
4
+ sendRequest(endpoint: string, data: any): Promise<any>;
5
+ getPendingRequest(): {
6
+ requestId: string;
7
+ request: {
8
+ endpoint: string;
9
+ data: any;
10
+ };
11
+ } | null;
12
+ resolveRequest(requestId: string, response: any): void;
13
+ rejectRequest(requestId: string, error: any): void;
14
+ cleanupOldRequests(): void;
15
+ clearAllPendingRequests(): void;
16
+ }
17
+ //# sourceMappingURL=bridge-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge-service.d.ts","sourceRoot":"","sources":["../src/bridge-service.ts"],"names":[],"mappings":"AAWA,qBAAa,aAAa;IACxB,OAAO,CAAC,eAAe,CAA0C;IACjE,OAAO,CAAC,cAAc,CAAS;IAEzB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;IAyB5D,iBAAiB,IAAI;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,GAAG,CAAA;SAAE,CAAA;KAAE,GAAG,IAAI;IAuB3F,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG;IAQ/C,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG;IAS3C,kBAAkB;IAWlB,uBAAuB;CAMxB"}
@@ -0,0 +1,77 @@
1
+ import { v4 as uuidv4 } from 'uuid';
2
+ export class BridgeService {
3
+ pendingRequests = new Map();
4
+ requestTimeout = 30000; // 30 seconds timeout
5
+ async sendRequest(endpoint, data) {
6
+ const requestId = uuidv4();
7
+ return new Promise((resolve, reject) => {
8
+ const request = {
9
+ id: requestId,
10
+ endpoint,
11
+ data,
12
+ timestamp: Date.now(),
13
+ resolve,
14
+ reject
15
+ };
16
+ this.pendingRequests.set(requestId, request);
17
+ // Set timeout
18
+ setTimeout(() => {
19
+ if (this.pendingRequests.has(requestId)) {
20
+ this.pendingRequests.delete(requestId);
21
+ reject(new Error('Request timeout'));
22
+ }
23
+ }, this.requestTimeout);
24
+ });
25
+ }
26
+ getPendingRequest() {
27
+ // Get oldest pending request
28
+ let oldestRequest = null;
29
+ for (const request of this.pendingRequests.values()) {
30
+ if (!oldestRequest || request.timestamp < oldestRequest.timestamp) {
31
+ oldestRequest = request;
32
+ }
33
+ }
34
+ if (oldestRequest) {
35
+ return {
36
+ requestId: oldestRequest.id,
37
+ request: {
38
+ endpoint: oldestRequest.endpoint,
39
+ data: oldestRequest.data
40
+ }
41
+ };
42
+ }
43
+ return null;
44
+ }
45
+ resolveRequest(requestId, response) {
46
+ const request = this.pendingRequests.get(requestId);
47
+ if (request) {
48
+ this.pendingRequests.delete(requestId);
49
+ request.resolve(response);
50
+ }
51
+ }
52
+ rejectRequest(requestId, error) {
53
+ const request = this.pendingRequests.get(requestId);
54
+ if (request) {
55
+ this.pendingRequests.delete(requestId);
56
+ request.reject(error);
57
+ }
58
+ }
59
+ // Clean up old requests
60
+ cleanupOldRequests() {
61
+ const now = Date.now();
62
+ for (const [id, request] of this.pendingRequests.entries()) {
63
+ if (now - request.timestamp > this.requestTimeout) {
64
+ this.pendingRequests.delete(id);
65
+ request.reject(new Error('Request timeout'));
66
+ }
67
+ }
68
+ }
69
+ // Force cleanup all pending requests (used on disconnect)
70
+ clearAllPendingRequests() {
71
+ for (const [id, request] of this.pendingRequests.entries()) {
72
+ request.reject(new Error('Connection closed'));
73
+ }
74
+ this.pendingRequests.clear();
75
+ }
76
+ }
77
+ //# sourceMappingURL=bridge-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge-service.js","sourceRoot":"","sources":["../src/bridge-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { RobloxStudioTools } from './tools/index.js';
2
+ import { BridgeService } from './bridge-service.js';
3
+ export declare function createHttpServer(tools: RobloxStudioTools, bridge: BridgeService): import("express-serve-static-core").Express;
4
+ //# sourceMappingURL=http-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-server.d.ts","sourceRoot":"","sources":["../src/http-server.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,iBAAiB,EAAE,MAAM,EAAE,aAAa,+CAkT/E"}