@el4cteo/rbx-studio-mcp 0.4.1 → 0.4.2
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@el4cteo/rbx-studio-mcp",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "MCP server for Roblox Studio. 29 tools, push-based SSE bridge, editor-safe script edits, one-step undo.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -45,11 +45,11 @@
|
|
|
45
45
|
"ai-agent"
|
|
46
46
|
],
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
49
|
-
"zod": "^4.4
|
|
48
|
+
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
49
|
+
"zod": "^4.5.4"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
|
-
"@types/node": "^26.
|
|
52
|
+
"@types/node": "^26.4.1",
|
|
53
53
|
"typescript": "^7.0.2"
|
|
54
54
|
},
|
|
55
55
|
"author": "EL4CTEO",
|
package/plugin/src/Config.luau
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
local Config = {}
|
|
11
11
|
|
|
12
|
-
Config.PLUGIN_VERSION = "0.4.
|
|
12
|
+
Config.PLUGIN_VERSION = "0.4.2"
|
|
13
13
|
|
|
14
14
|
-- Fingerprint of plugin/src, stamped in by scripts/build-plugin.mjs. The server
|
|
15
15
|
-- computes the same hash from its own copy of the sources and compares, so a
|
|
@@ -37,6 +37,14 @@ local Api = require(script.handlers.Api)
|
|
|
37
37
|
local Scripts = require(script.handlers.Scripts)
|
|
38
38
|
local Session = require(script.handlers.Session)
|
|
39
39
|
|
|
40
|
+
--[[
|
|
41
|
+
How long a closed panel has to stay closed before that is written down.
|
|
42
|
+
|
|
43
|
+
Long enough to outlast Studio tearing a place down, short enough that a user
|
|
44
|
+
who closes the panel and quits immediately still has it remembered.
|
|
45
|
+
]]
|
|
46
|
+
local WIDGET_CLOSE_GRACE = 1
|
|
47
|
+
|
|
40
48
|
local SETTING_PORT = "port"
|
|
41
49
|
local SETTING_AUTOCONNECT = "autoConnect"
|
|
42
50
|
local SETTING_FORCE_POLL = "forcePoll"
|
|
@@ -243,10 +251,40 @@ if RunService:IsEdit() then
|
|
|
243
251
|
unloading = true
|
|
244
252
|
end)
|
|
245
253
|
|
|
254
|
+
--[[
|
|
255
|
+
Only a close the user actually asked for is remembered.
|
|
256
|
+
|
|
257
|
+
Opening is recorded at once -- there is no teardown that opens a panel,
|
|
258
|
+
so a `true` is always the user. A `false` is not: Studio disables the
|
|
259
|
+
widget on its way out of a place, and `plugin.Unloading` is not
|
|
260
|
+
guaranteed to have fired by then, so the `unloading` flag alone lost the
|
|
261
|
+
race often enough that people found the panel closed on their next
|
|
262
|
+
launch with no memory of closing it. That is the "it does not open any
|
|
263
|
+
more" report, and it was self-inflicted and permanent -- once `false` is
|
|
264
|
+
stored, nothing writes `true` again until the panel is opened by hand.
|
|
265
|
+
|
|
266
|
+
So a close has to survive a moment before it counts. A teardown never
|
|
267
|
+
does: the DataModel is gone long before the delay is up, taking the
|
|
268
|
+
pending write with it. A user clicking the X does, and a user who
|
|
269
|
+
re-opens within the delay cancels it, which is also correct.
|
|
270
|
+
]]
|
|
271
|
+
local closeGeneration = 0
|
|
246
272
|
widget:GetPropertyChangedSignal("Enabled"):Connect(function()
|
|
247
|
-
if
|
|
248
|
-
|
|
273
|
+
if unloading then
|
|
274
|
+
return
|
|
275
|
+
end
|
|
276
|
+
closeGeneration += 1
|
|
277
|
+
if widget.Enabled then
|
|
278
|
+
plugin:SetSetting(SETTING_WIDGET_OPEN, true)
|
|
279
|
+
return
|
|
249
280
|
end
|
|
281
|
+
local generation = closeGeneration
|
|
282
|
+
task.delay(WIDGET_CLOSE_GRACE, function()
|
|
283
|
+
if unloading or generation ~= closeGeneration or widget.Enabled then
|
|
284
|
+
return
|
|
285
|
+
end
|
|
286
|
+
plugin:SetSetting(SETTING_WIDGET_OPEN, false)
|
|
287
|
+
end)
|
|
250
288
|
end)
|
|
251
289
|
|
|
252
290
|
-- Only a real, sane size, and only while the panel is up: a hidden or
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* Usage: node scripts/install-plugin.mjs
|
|
8
8
|
*/
|
|
9
9
|
import { execFileSync } from "node:child_process";
|
|
10
|
-
import { copyFileSync, existsSync, mkdirSync } from "node:fs";
|
|
10
|
+
import { copyFileSync, existsSync, mkdirSync, renameSync, rmSync } from "node:fs";
|
|
11
11
|
import { homedir } from "node:os";
|
|
12
12
|
import { dirname, join, resolve } from "node:path";
|
|
13
13
|
import { fileURLToPath } from "node:url";
|
|
@@ -36,4 +36,27 @@ execFileSync(process.execPath, [join(root, "scripts", "build-plugin.mjs")], { st
|
|
|
36
36
|
|
|
37
37
|
const target = pluginsDir();
|
|
38
38
|
if (!existsSync(target)) mkdirSync(target, { recursive: true });
|
|
39
|
-
|
|
39
|
+
|
|
40
|
+
/*
|
|
41
|
+
* Copied beside the target and renamed over it, never written in place.
|
|
42
|
+
*
|
|
43
|
+
* Studio watches this directory and reloads the moment the file changes, so an
|
|
44
|
+
* in-place copy hands it whatever is on disk at that instant -- which, for a
|
|
45
|
+
* file of this size, is regularly half of one build and none of the next. The
|
|
46
|
+
* plugin then fails to parse and Studio drops it silently: no toolbar button,
|
|
47
|
+
* nothing in the plugin list, and no error saying why. It reads as the plugin
|
|
48
|
+
* randomly not being installed, and re-running the install "fixes" it, which is
|
|
49
|
+
* exactly what you would expect from a race.
|
|
50
|
+
*
|
|
51
|
+
* Rename within one directory is atomic, so Studio sees the old file or the new
|
|
52
|
+
* one and never the seam between them.
|
|
53
|
+
*/
|
|
54
|
+
const destination = join(target, "StudioMCP.rbxmx");
|
|
55
|
+
const staged = join(target, "StudioMCP.rbxmx.incoming");
|
|
56
|
+
try {
|
|
57
|
+
copyFileSync(built, staged);
|
|
58
|
+
renameSync(staged, destination);
|
|
59
|
+
} catch (cause) {
|
|
60
|
+
rmSync(staged, { force: true });
|
|
61
|
+
throw cause;
|
|
62
|
+
}
|