@el4cteo/rbx-studio-mcp 0.4.5 → 0.5.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.
- package/README.md +46 -4
- package/dist/bridge/api.js +22 -3
- package/dist/bridge/api.js.map +1 -1
- package/dist/bridge/console.js +279 -0
- package/dist/bridge/console.js.map +1 -0
- package/dist/bridge/harness.js +513 -0
- package/dist/bridge/harness.js.map +1 -0
- package/dist/bridge/remote.js +9 -1
- package/dist/bridge/remote.js.map +1 -1
- package/dist/bridge/rpc.js +69 -4
- package/dist/bridge/rpc.js.map +1 -1
- package/dist/bridge/server.js +54 -6
- package/dist/bridge/server.js.map +1 -1
- package/dist/doctor.js +13 -1
- package/dist/doctor.js.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/protocol.js.map +1 -1
- package/dist/tools/screenshot.js +7 -6
- package/dist/tools/screenshot.js.map +1 -1
- package/dist/tools/terrain.js +116 -0
- package/dist/tools/terrain.js.map +1 -0
- package/package.json +4 -4
- package/plugin/src/Commands.luau +524 -0
- package/plugin/src/Config.luau +1 -1
- package/plugin/src/Console.luau +282 -49
- package/plugin/src/Format.luau +114 -0
- package/plugin/src/Prompt.luau +436 -0
- package/plugin/src/ScriptEdit.luau +48 -0
- package/plugin/src/Visuals.luau +1409 -1332
- package/plugin/src/handlers/Capture.luau +68 -20
- package/plugin/src/handlers/Terrain.luau +371 -0
- package/plugin/src/init.server.luau +829 -725
- package/scripts/test-console.mjs +293 -0
- package/scripts/test-failover.mjs +47 -0
- package/scripts/test-plugin.mjs +85 -82
|
@@ -0,0 +1,513 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runs a coding agent next to the user, on the panel's behalf.
|
|
3
|
+
*
|
|
4
|
+
* The console panel has a prompt line, and free text typed into it is not a
|
|
5
|
+
* command -- it is a request for an agent. MCP gives no way to deliver that to
|
|
6
|
+
* the agent already attached to this bridge: a server answers clients, it never
|
|
7
|
+
* calls them, so there is no inbound channel into a session someone is sitting
|
|
8
|
+
* in. What there IS, on every machine that has one of these tools installed, is
|
|
9
|
+
* a headless mode. So the bridge starts its own.
|
|
10
|
+
*
|
|
11
|
+
* The agent it starts connects back to this same bridge as an ordinary MCP
|
|
12
|
+
* client -- the port is taken, so its server becomes a peer and proxies -- and
|
|
13
|
+
* drives the same Studio the user is looking at. Its output is streamed into
|
|
14
|
+
* the console log line by line, which is what makes the panel its face rather
|
|
15
|
+
* than a black box with a spinner.
|
|
16
|
+
*
|
|
17
|
+
* Deliberately a registry rather than a `claude` integration. Users arrive with
|
|
18
|
+
* whatever harness they already use, and every one of them ships the same three
|
|
19
|
+
* things: a binary, a one-shot flag, and a way to ask for machine-readable
|
|
20
|
+
* output. Adding one is a table entry, and a harness nobody wrote an adapter
|
|
21
|
+
* for still works through `generic`, which simply prints what it prints.
|
|
22
|
+
*/
|
|
23
|
+
import { spawn } from "node:child_process";
|
|
24
|
+
import { existsSync, mkdtempSync, writeFileSync } from "node:fs";
|
|
25
|
+
import { tmpdir } from "node:os";
|
|
26
|
+
import { delimiter, dirname, join, resolve } from "node:path";
|
|
27
|
+
import { fileURLToPath } from "node:url";
|
|
28
|
+
const NOTHING = { lines: [] };
|
|
29
|
+
/** JSON if it parses, null otherwise. Harness stdout carries plain lines too. */
|
|
30
|
+
function parse(line) {
|
|
31
|
+
const text = line.trim();
|
|
32
|
+
if (text === "" || (text[0] !== "{" && text[0] !== "["))
|
|
33
|
+
return null;
|
|
34
|
+
try {
|
|
35
|
+
return JSON.parse(text);
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/** A tool call written the way the console writes its own. */
|
|
42
|
+
function toolLine(name, input) {
|
|
43
|
+
const short = name.replace(/^mcp__[^_]+__/, "").replace(/^mcp__/, "");
|
|
44
|
+
let detail;
|
|
45
|
+
if (input !== null && typeof input === "object") {
|
|
46
|
+
const parts = Object.entries(input)
|
|
47
|
+
.filter(([, value]) => typeof value === "string" || typeof value === "number")
|
|
48
|
+
.slice(0, 2)
|
|
49
|
+
// Flattened before it is cut, not after: a Luau snippet passed to
|
|
50
|
+
// execute_luau is multi-line, and 32 characters of it took a newline
|
|
51
|
+
// along into a log whose rows are lines.
|
|
52
|
+
.map(([key, value]) => key + "=" + String(value).replace(/\s+/g, " ").slice(0, 32));
|
|
53
|
+
if (parts.length > 0)
|
|
54
|
+
detail = parts.join(" ");
|
|
55
|
+
}
|
|
56
|
+
return { level: "call", message: short, detail };
|
|
57
|
+
}
|
|
58
|
+
/** Collapses a paragraph into the one-line rows a console log can hold. */
|
|
59
|
+
function say(text) {
|
|
60
|
+
return text
|
|
61
|
+
.split("\n")
|
|
62
|
+
.map((piece) => piece.trim())
|
|
63
|
+
.filter((piece) => piece !== "")
|
|
64
|
+
.map((piece) => ({ level: "reply", message: piece }));
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Claude Code. `--print` with `stream-json` emits one JSON object per step,
|
|
68
|
+
* which is exactly the granularity this log wants: a row per thought and a row
|
|
69
|
+
* per tool call, rather than a wall of text at the end.
|
|
70
|
+
*/
|
|
71
|
+
const claude = {
|
|
72
|
+
id: "claude",
|
|
73
|
+
label: "Claude Code",
|
|
74
|
+
bin: "claude",
|
|
75
|
+
mcpFlag: () => ["--mcp-config", mcpConfig()],
|
|
76
|
+
argv: (prompt, session) => [
|
|
77
|
+
...(session === null ? [] : ["--resume", session]),
|
|
78
|
+
"--print",
|
|
79
|
+
prompt,
|
|
80
|
+
"--output-format",
|
|
81
|
+
"stream-json",
|
|
82
|
+
"--verbose",
|
|
83
|
+
// A headless agent cannot show an approval dialog, so what it may do is
|
|
84
|
+
// decided here rather than asked for later. Studio tools and nothing else:
|
|
85
|
+
// this prompt came from a Studio panel, and a request typed there is not
|
|
86
|
+
// consent to edit the user's disk.
|
|
87
|
+
"--allowedTools",
|
|
88
|
+
"mcp__rbx-studio",
|
|
89
|
+
"--permission-mode",
|
|
90
|
+
"dontAsk",
|
|
91
|
+
],
|
|
92
|
+
read: (line) => {
|
|
93
|
+
const event = parse(line);
|
|
94
|
+
if (event === null)
|
|
95
|
+
return NOTHING;
|
|
96
|
+
if (event.type === "system" && event.subtype === "init") {
|
|
97
|
+
return { lines: [], session: event.session_id };
|
|
98
|
+
}
|
|
99
|
+
if (event.type === "assistant") {
|
|
100
|
+
const lines = [];
|
|
101
|
+
for (const part of event.message?.content ?? []) {
|
|
102
|
+
if (part.type === "text" && String(part.text).trim() !== "")
|
|
103
|
+
lines.push(...say(part.text));
|
|
104
|
+
if (part.type === "tool_use")
|
|
105
|
+
lines.push(toolLine(part.name, part.input));
|
|
106
|
+
}
|
|
107
|
+
return { lines, session: event.session_id };
|
|
108
|
+
}
|
|
109
|
+
if (event.type === "result") {
|
|
110
|
+
const cost = typeof event.total_cost_usd === "number" ? "$" + event.total_cost_usd.toFixed(4) : "";
|
|
111
|
+
const took = typeof event.duration_ms === "number" ? (event.duration_ms / 1000).toFixed(1) + "s" : "";
|
|
112
|
+
const detail = [took, cost].filter((piece) => piece !== "").join(" ");
|
|
113
|
+
return {
|
|
114
|
+
lines: [
|
|
115
|
+
{
|
|
116
|
+
level: event.is_error === true ? "error" : "ok",
|
|
117
|
+
message: event.is_error === true ? "agent failed" : "agent done",
|
|
118
|
+
detail: detail === "" ? undefined : detail,
|
|
119
|
+
},
|
|
120
|
+
],
|
|
121
|
+
session: event.session_id,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
return NOTHING;
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
/**
|
|
128
|
+
* OpenAI Codex CLI. `exec` is its headless verb and `--json` its event stream;
|
|
129
|
+
* the envelope differs from Claude's but carries the same three facts.
|
|
130
|
+
*/
|
|
131
|
+
const codex = {
|
|
132
|
+
id: "codex",
|
|
133
|
+
label: "Codex CLI",
|
|
134
|
+
bin: "codex",
|
|
135
|
+
argv: (prompt, session) => [
|
|
136
|
+
"exec",
|
|
137
|
+
...(session === null ? [] : ["resume", session]),
|
|
138
|
+
"--json",
|
|
139
|
+
"--skip-git-repo-check",
|
|
140
|
+
prompt,
|
|
141
|
+
],
|
|
142
|
+
read: (line) => {
|
|
143
|
+
const event = parse(line);
|
|
144
|
+
if (event === null)
|
|
145
|
+
return NOTHING;
|
|
146
|
+
const item = event.item ?? event.msg ?? event;
|
|
147
|
+
const kind = item.type ?? event.type;
|
|
148
|
+
if (kind === "session.created" || kind === "session_configured") {
|
|
149
|
+
return { lines: [], session: item.session_id ?? event.session_id };
|
|
150
|
+
}
|
|
151
|
+
if (kind === "agent_message" || kind === "assistant_message") {
|
|
152
|
+
return { lines: say(String(item.text ?? item.message ?? "")) };
|
|
153
|
+
}
|
|
154
|
+
if (kind === "command_execution" || kind === "mcp_tool_call" || kind === "function_call") {
|
|
155
|
+
const name = String(item.tool ?? item.name ?? item.command ?? "tool");
|
|
156
|
+
return { lines: [toolLine(name, item.arguments ?? item.input)] };
|
|
157
|
+
}
|
|
158
|
+
if (kind === "turn.completed" || kind === "task_complete") {
|
|
159
|
+
return { lines: [{ level: "ok", message: "agent done" }] };
|
|
160
|
+
}
|
|
161
|
+
if (kind === "error" || kind === "turn.failed") {
|
|
162
|
+
return { lines: [{ level: "error", message: String(item.message ?? "agent failed") }] };
|
|
163
|
+
}
|
|
164
|
+
return NOTHING;
|
|
165
|
+
},
|
|
166
|
+
};
|
|
167
|
+
/** opencode. `run` is one-shot; `--format json` turns it into an event stream. */
|
|
168
|
+
const opencode = {
|
|
169
|
+
id: "opencode",
|
|
170
|
+
label: "opencode",
|
|
171
|
+
bin: "opencode",
|
|
172
|
+
argv: (prompt, session) => [
|
|
173
|
+
"run",
|
|
174
|
+
...(session === null ? [] : ["--session", session]),
|
|
175
|
+
"--format",
|
|
176
|
+
"json",
|
|
177
|
+
prompt,
|
|
178
|
+
],
|
|
179
|
+
read: (line) => {
|
|
180
|
+
const event = parse(line);
|
|
181
|
+
if (event === null) {
|
|
182
|
+
return line.trim() === "" ? NOTHING : { lines: [{ level: "dim", message: line.trim() }] };
|
|
183
|
+
}
|
|
184
|
+
const kind = event.type ?? event.event;
|
|
185
|
+
if (kind === "session.created" || kind === "session") {
|
|
186
|
+
return { lines: [], session: event.sessionID ?? event.id ?? event.properties?.info?.id };
|
|
187
|
+
}
|
|
188
|
+
if (kind === "message.part.updated" || kind === "part") {
|
|
189
|
+
const part = event.properties?.part ?? event.part ?? {};
|
|
190
|
+
if (part.type === "text" && typeof part.text === "string")
|
|
191
|
+
return { lines: say(part.text) };
|
|
192
|
+
if (part.type === "tool" && typeof part.tool === "string") {
|
|
193
|
+
return { lines: [toolLine(part.tool, part.state?.input)] };
|
|
194
|
+
}
|
|
195
|
+
return NOTHING;
|
|
196
|
+
}
|
|
197
|
+
if (kind === "session.idle" || kind === "done") {
|
|
198
|
+
return { lines: [{ level: "ok", message: "agent done" }] };
|
|
199
|
+
}
|
|
200
|
+
return NOTHING;
|
|
201
|
+
},
|
|
202
|
+
};
|
|
203
|
+
/**
|
|
204
|
+
* Anything else on PATH, printed as it prints.
|
|
205
|
+
*
|
|
206
|
+
* Worth having even though it understands nothing: a harness with no adapter
|
|
207
|
+
* still shows its work in the panel, which is the whole point, and writing a
|
|
208
|
+
* real adapter later only changes how tidy it looks.
|
|
209
|
+
*/
|
|
210
|
+
function generic(id, bin, label) {
|
|
211
|
+
return {
|
|
212
|
+
id,
|
|
213
|
+
label,
|
|
214
|
+
bin,
|
|
215
|
+
argv: (prompt) => ["-p", prompt],
|
|
216
|
+
read: (line) => line.trim() === "" ? NOTHING : { lines: [{ level: "dim", message: line.trim() }] },
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* DeepSeek Harness. `--profile headless` is its one-shot verb: one fresh
|
|
221
|
+
* session, the final answer on stdout, exit.
|
|
222
|
+
*
|
|
223
|
+
* No event stream and no `--resume` on that profile -- both belong to its
|
|
224
|
+
* terminal and SDK profiles -- so this reads plain lines and starts a new
|
|
225
|
+
* conversation each time. That is a real limitation rather than a gap in this
|
|
226
|
+
* adapter, and it is why `say` gets the whole answer at the end instead of a
|
|
227
|
+
* row per step.
|
|
228
|
+
*
|
|
229
|
+
* The overlay is passed on every run rather than asking the user to install it,
|
|
230
|
+
* so a prompt typed in the panel reaches Studio whether or not they have
|
|
231
|
+
* merged the row into their own patch layer.
|
|
232
|
+
*/
|
|
233
|
+
const dsh = {
|
|
234
|
+
id: "dsh",
|
|
235
|
+
label: "DeepSeek Harness",
|
|
236
|
+
bin: "dsh",
|
|
237
|
+
//[[ Built here rather than through `mcpFlag`, because order is load-bearing.
|
|
238
|
+
//
|
|
239
|
+
// `dsh [options] [command] [args...]`: `--patch` is a launcher option and the
|
|
240
|
+
// prompt is a positional argument for the booted profile, so the flag has to
|
|
241
|
+
// come first. `mcpFlag` appends, which would have put it after the prompt.
|
|
242
|
+
//]]
|
|
243
|
+
argv: (prompt) => ["--profile", "headless", "--patch", dshOverlay(), prompt],
|
|
244
|
+
read: (line) => line.trim() === "" ? NOTHING : { lines: [{ level: "reply", message: line.trim() }] },
|
|
245
|
+
};
|
|
246
|
+
const REGISTRY = [
|
|
247
|
+
claude,
|
|
248
|
+
codex,
|
|
249
|
+
opencode,
|
|
250
|
+
dsh,
|
|
251
|
+
generic("gemini", "gemini", "Gemini CLI"),
|
|
252
|
+
generic("cursor", "cursor-agent", "Cursor Agent"),
|
|
253
|
+
generic("crush", "crush", "Crush"),
|
|
254
|
+
];
|
|
255
|
+
/**
|
|
256
|
+
* Where a binary is on PATH, or null. Found by looking rather than by running.
|
|
257
|
+
*
|
|
258
|
+
* Running `--version` to find out costs a process per candidate on every
|
|
259
|
+
* `agent` listing, and several of these tools take a second to start.
|
|
260
|
+
*
|
|
261
|
+
* The full path matters beyond the yes/no answer. On Windows every one of these
|
|
262
|
+
* tools is installed as a `.cmd` shim, and Node only applies its cmd-specific
|
|
263
|
+
* argument escaping when it can SEE that extension. Handed a bare "claude" with
|
|
264
|
+
* `shell: true` it concatenates instead, which strips every quote in the
|
|
265
|
+
* command line -- that is not just a formatting bug, it is the difference
|
|
266
|
+
* between passing a prompt and pasting whatever is in it into a shell.
|
|
267
|
+
*/
|
|
268
|
+
function whereIs(bin) {
|
|
269
|
+
const paths = (process.env["PATH"] ?? "").split(delimiter).filter((entry) => entry !== "");
|
|
270
|
+
const extensions = process.platform === "win32"
|
|
271
|
+
? (process.env["PATHEXT"] ?? ".EXE;.CMD;.BAT").split(";")
|
|
272
|
+
: [""];
|
|
273
|
+
for (const dir of paths) {
|
|
274
|
+
for (const extension of extensions) {
|
|
275
|
+
for (const candidate of extension === ""
|
|
276
|
+
? [join(dir, bin)]
|
|
277
|
+
: [join(dir, bin + extension), join(dir, bin + extension.toLowerCase())]) {
|
|
278
|
+
if (existsSync(candidate))
|
|
279
|
+
return candidate;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return null;
|
|
284
|
+
}
|
|
285
|
+
export function installed() {
|
|
286
|
+
return REGISTRY.filter((entry) => whereIs(entry.bin) !== null);
|
|
287
|
+
}
|
|
288
|
+
export function find(id) {
|
|
289
|
+
return REGISTRY.find((entry) => entry.id === id || entry.bin === id);
|
|
290
|
+
}
|
|
291
|
+
/** Written once per process, reused by every run. */
|
|
292
|
+
let configPath = null;
|
|
293
|
+
/**
|
|
294
|
+
* An MCP config naming THIS package, written to a file.
|
|
295
|
+
*
|
|
296
|
+
* A file rather than the inline JSON string these flags also accept, because
|
|
297
|
+
* the string is a brace-and-quote-heavy argument crossing a Windows command
|
|
298
|
+
* line, and the first attempt at it arrived at the other end with every quote
|
|
299
|
+
* gone. A path has nothing in it to mangle.
|
|
300
|
+
*
|
|
301
|
+
* Points at our own entry rather than at `npx` so the agent cannot end up
|
|
302
|
+
* driving a different version of the bridge than the one it is talking to.
|
|
303
|
+
*/
|
|
304
|
+
function mcpConfig() {
|
|
305
|
+
if (configPath !== null)
|
|
306
|
+
return configPath;
|
|
307
|
+
const entry = resolve(dirname(fileURLToPath(import.meta.url)), "..", "index.js");
|
|
308
|
+
const dir = mkdtempSync(join(tmpdir(), "rbx-studio-mcp-"));
|
|
309
|
+
configPath = join(dir, "mcp.json");
|
|
310
|
+
writeFileSync(configPath, JSON.stringify({
|
|
311
|
+
mcpServers: {
|
|
312
|
+
"rbx-studio": {
|
|
313
|
+
command: process.execPath,
|
|
314
|
+
args: [entry],
|
|
315
|
+
//[[ Stated here as well as in the spawn's own environment.
|
|
316
|
+
//
|
|
317
|
+
// The agent inherits RBX_STUDIO_MCP_SPAWNED, but the agent is not
|
|
318
|
+
// what connects: it launches its own copy of this server as a child,
|
|
319
|
+
// and whether that child inherits the agent's environment is the
|
|
320
|
+
// agent's business, not ours. Claude's did not, so the spawned server
|
|
321
|
+
// announced itself as a stranger -- the panel said "2 MCP clients
|
|
322
|
+
// connected" on every prompt, and a stopped agent stayed in `clients`
|
|
323
|
+
// until the 90-second stale timeout swept it.
|
|
324
|
+
//
|
|
325
|
+
// Written into the config the agent reads, it survives whatever the
|
|
326
|
+
// agent does to the environment on the way.
|
|
327
|
+
//]]
|
|
328
|
+
env: { RBX_STUDIO_MCP_SPAWNED: "1" },
|
|
329
|
+
},
|
|
330
|
+
},
|
|
331
|
+
}), "utf8");
|
|
332
|
+
return configPath;
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Ends a run, and everything it started.
|
|
336
|
+
*
|
|
337
|
+
* `child.kill()` is not enough, and the way it fails is the worst kind: it
|
|
338
|
+
* returns true, the streams close, the promise settles, the panel says
|
|
339
|
+
* "stopping the agent" and goes back to idle -- and the agent carries on
|
|
340
|
+
* editing the user's place. Measured on Windows, `claude.exe` was still running
|
|
341
|
+
* five seconds after a cancel that reported success, because what actually died
|
|
342
|
+
* was the launcher holding the pipes while the work ran in a descendant.
|
|
343
|
+
*
|
|
344
|
+
* So the tree goes, not the process. `taskkill /T` walks the children on
|
|
345
|
+
* Windows; elsewhere the child was given its own process group at spawn, and
|
|
346
|
+
* the negative pid signals all of it. Both fall back to the plain kill, because
|
|
347
|
+
* a cancel that half works still beats one that throws.
|
|
348
|
+
*/
|
|
349
|
+
function kill(child) {
|
|
350
|
+
const pid = child.pid;
|
|
351
|
+
if (pid === undefined)
|
|
352
|
+
return;
|
|
353
|
+
if (process.platform === "win32") {
|
|
354
|
+
try {
|
|
355
|
+
spawn("taskkill", ["/pid", String(pid), "/T", "/F"], { stdio: "ignore" });
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
catch {
|
|
359
|
+
/* falls through to the plain kill */
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
else {
|
|
363
|
+
try {
|
|
364
|
+
process.kill(-pid, "SIGTERM");
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
catch {
|
|
368
|
+
/* the group is gone, or was never made */
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
child.kill();
|
|
372
|
+
}
|
|
373
|
+
let overlayPath = null;
|
|
374
|
+
/**
|
|
375
|
+
* The same server, written as the Cordis overlay row dsh reads.
|
|
376
|
+
*
|
|
377
|
+
* A second format rather than a translation of the first, because the two are
|
|
378
|
+
* not the same statement: dsh's row also fixes the tool namespace, the per-call
|
|
379
|
+
* timeout, and what happens when Studio is not open yet. Kept byte-identical in
|
|
380
|
+
* meaning to `config/dsh.cordis.yml`, which is the copy a user merges into
|
|
381
|
+
* their own profile -- this one exists so a panel prompt works before they have.
|
|
382
|
+
*/
|
|
383
|
+
function dshOverlay() {
|
|
384
|
+
if (overlayPath !== null)
|
|
385
|
+
return overlayPath;
|
|
386
|
+
const entry = resolve(dirname(fileURLToPath(import.meta.url)), "..", "index.js");
|
|
387
|
+
const dir = mkdtempSync(join(tmpdir(), "rbx-studio-mcp-"));
|
|
388
|
+
overlayPath = join(dir, "rbx-studio.cordis.yml");
|
|
389
|
+
// Written by hand rather than through a YAML library: it is six fixed keys
|
|
390
|
+
// and one interpolated path, and a dependency for that is a dependency to
|
|
391
|
+
// keep patched forever.
|
|
392
|
+
writeFileSync(overlayPath, [
|
|
393
|
+
"- insert:",
|
|
394
|
+
" - id: mcp-rbx-studio",
|
|
395
|
+
" name: '@deepseek-ai/dsh-mcp-client'",
|
|
396
|
+
" config:",
|
|
397
|
+
" serverName: rbx-studio",
|
|
398
|
+
" transport: stdio",
|
|
399
|
+
` command: ${JSON.stringify(process.execPath)}`,
|
|
400
|
+
` args: [${JSON.stringify(entry)}]`,
|
|
401
|
+
" toolCallTimeoutMs: 60000",
|
|
402
|
+
" failOnStartupError: false",
|
|
403
|
+
// The same declaration as the Claude config's `env`, for the same
|
|
404
|
+
// reason: what dsh passes to a server it starts is dsh's business.
|
|
405
|
+
" env:",
|
|
406
|
+
" RBX_STUDIO_MCP_SPAWNED: '1'",
|
|
407
|
+
"",
|
|
408
|
+
].join("\n"), "utf8");
|
|
409
|
+
return overlayPath;
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Starts `harness` on `prompt`, reporting every step through `emit`.
|
|
413
|
+
*
|
|
414
|
+
* stdout is read line by line because every adapter here is line-oriented, and
|
|
415
|
+
* a chunk boundary lands mid-object often enough that not buffering shows up as
|
|
416
|
+
* randomly missing rows rather than as an obvious break.
|
|
417
|
+
*/
|
|
418
|
+
export function run(harness, prompt, options) {
|
|
419
|
+
const argv = [...harness.argv(prompt, options.session)];
|
|
420
|
+
if (harness.mcpFlag !== undefined)
|
|
421
|
+
argv.push(...harness.mcpFlag());
|
|
422
|
+
const executable = whereIs(harness.bin);
|
|
423
|
+
if (executable === null) {
|
|
424
|
+
options.emit({ level: "error", message: harness.bin + " is not on PATH" });
|
|
425
|
+
return { cancel: () => { }, done: Promise.resolve(null) };
|
|
426
|
+
}
|
|
427
|
+
let child;
|
|
428
|
+
try {
|
|
429
|
+
child = spawn(executable, argv, {
|
|
430
|
+
cwd: options.cwd,
|
|
431
|
+
// Only for the .cmd shims Windows installs these as, which CreateProcess
|
|
432
|
+
// will not run. Node escapes arguments correctly for those precisely
|
|
433
|
+
// because the extension is visible in the path; anything else is spawned
|
|
434
|
+
// directly, with no shell to quote for.
|
|
435
|
+
shell: /\.(cmd|bat)$/i.test(executable),
|
|
436
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
437
|
+
// Its own process group, so cancelling can take the whole tree down with
|
|
438
|
+
// one signal. See `kill`.
|
|
439
|
+
detached: process.platform !== "win32",
|
|
440
|
+
// Travels down to the MCP server this agent will start, which is the only
|
|
441
|
+
// thing in a position to tell the bridge that its client was not a person
|
|
442
|
+
// opening a second editor. See ClientView.spawned.
|
|
443
|
+
env: { ...process.env, RBX_STUDIO_MCP_SPAWNED: "1" },
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
catch (cause) {
|
|
447
|
+
const message = cause instanceof Error ? cause.message : String(cause);
|
|
448
|
+
options.emit({ level: "error", message: "could not start " + harness.bin, detail: message });
|
|
449
|
+
return { cancel: () => { }, done: Promise.resolve(null) };
|
|
450
|
+
}
|
|
451
|
+
let session = options.session;
|
|
452
|
+
let pending = "";
|
|
453
|
+
// Set by `cancel`, so a non-zero exit can be reported as the stop the user
|
|
454
|
+
// asked for rather than as a failure they did not.
|
|
455
|
+
let stopped = false;
|
|
456
|
+
const feed = (chunk) => {
|
|
457
|
+
pending += chunk;
|
|
458
|
+
let cut = pending.indexOf("\n");
|
|
459
|
+
while (cut !== -1) {
|
|
460
|
+
const line = pending.slice(0, cut);
|
|
461
|
+
pending = pending.slice(cut + 1);
|
|
462
|
+
const reading = harness.read(line);
|
|
463
|
+
if (reading.session !== undefined && reading.session !== "")
|
|
464
|
+
session = reading.session;
|
|
465
|
+
for (const row of reading.lines)
|
|
466
|
+
options.emit(row);
|
|
467
|
+
cut = pending.indexOf("\n");
|
|
468
|
+
}
|
|
469
|
+
};
|
|
470
|
+
child.stdout?.setEncoding("utf8");
|
|
471
|
+
child.stdout?.on("data", feed);
|
|
472
|
+
// stderr is where these tools put the reason they refused to start, and that
|
|
473
|
+
// is the single most useful line the panel can show when nothing happens.
|
|
474
|
+
let complaint = "";
|
|
475
|
+
child.stderr?.setEncoding("utf8");
|
|
476
|
+
child.stderr?.on("data", (chunk) => {
|
|
477
|
+
complaint = (complaint + chunk).slice(-400);
|
|
478
|
+
});
|
|
479
|
+
const done = new Promise((settle) => {
|
|
480
|
+
child.on("error", (cause) => {
|
|
481
|
+
options.emit({
|
|
482
|
+
level: "error",
|
|
483
|
+
message: "could not start " + harness.bin,
|
|
484
|
+
detail: cause.message,
|
|
485
|
+
});
|
|
486
|
+
settle(session);
|
|
487
|
+
});
|
|
488
|
+
child.on("close", (code) => {
|
|
489
|
+
if (pending !== "")
|
|
490
|
+
feed("\n");
|
|
491
|
+
if (stopped) {
|
|
492
|
+
options.emit({ level: "warn", message: "agent stopped" });
|
|
493
|
+
}
|
|
494
|
+
else if (code !== 0 && code !== null) {
|
|
495
|
+
const tail = complaint.trim().split("\n").slice(-2).join(" ");
|
|
496
|
+
options.emit({
|
|
497
|
+
level: "error",
|
|
498
|
+
message: harness.label + " exited " + code,
|
|
499
|
+
detail: tail === "" ? undefined : tail,
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
settle(session);
|
|
503
|
+
});
|
|
504
|
+
});
|
|
505
|
+
return {
|
|
506
|
+
cancel: () => {
|
|
507
|
+
stopped = true;
|
|
508
|
+
kill(child);
|
|
509
|
+
},
|
|
510
|
+
done,
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
//# sourceMappingURL=harness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness.js","sourceRoot":"","sources":["../../src/bridge/harness.ts"],"names":[],"mappings":"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"}
|
package/dist/bridge/remote.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { CLIENT_HEADER, PROTOCOL_VERSION } from "../lib/protocol.js";
|
|
3
3
|
import { ToolError } from "../lib/errors.js";
|
|
4
|
+
import { SPAWNED_BY_PANEL } from "./api.js";
|
|
4
5
|
/**
|
|
5
6
|
* Names this process to the owner, so its chosen Studio stays its own.
|
|
6
7
|
*
|
|
@@ -80,7 +81,14 @@ export class RemoteBridge {
|
|
|
80
81
|
/** Best effort: failing to register costs a badge, never a call. */
|
|
81
82
|
async hello() {
|
|
82
83
|
try {
|
|
83
|
-
await this.post("/hello", {
|
|
84
|
+
await this.post("/hello", {
|
|
85
|
+
name: this.about?.name,
|
|
86
|
+
version: this.about?.version,
|
|
87
|
+
pid: process.pid,
|
|
88
|
+
// Not from `this.about`, which is null on the first hello -- and the
|
|
89
|
+
// first hello is the one that gets announced. See SPAWNED_BY_PANEL.
|
|
90
|
+
spawned: SPAWNED_BY_PANEL,
|
|
91
|
+
}, 5_000);
|
|
84
92
|
}
|
|
85
93
|
catch {
|
|
86
94
|
/* ignored */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remote.js","sourceRoot":"","sources":["../../src/bridge/remote.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"remote.js","sourceRoot":"","sources":["../../src/bridge/remote.ts"],"names":[],"mappings":"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"}
|