@rainbow-robotics/muscat-plugin-kit 0.1.2-dev.49 → 0.1.2-dev.50
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/cli/src/bridge.mjs +1 -1
- package/cli/src/dev.mjs +7 -2
- package/cli/src/devBack.mjs +33 -9
- package/cli/src/devUi.mjs +9 -3
- package/cli/src/new.mjs +1 -1
- package/cli/storybook-dist/project.json +1 -1
- package/package.json +3 -3
package/cli/src/bridge.mjs
CHANGED
|
@@ -75,7 +75,7 @@ export async function startBridge() {
|
|
|
75
75
|
log.step("starting Socket.IO bridge container…");
|
|
76
76
|
const up = spawnSync(
|
|
77
77
|
"docker",
|
|
78
|
-
["run", "-d", "--name", BRIDGE_CONTAINER, "-p",
|
|
78
|
+
["run", "-d", "--name", BRIDGE_CONTAINER, "-p", `127.0.0.1:${BRIDGE_PORT}:${BRIDGE_PORT}`, BRIDGE_IMAGE],
|
|
79
79
|
{ stdio: "inherit" },
|
|
80
80
|
);
|
|
81
81
|
if (up.status !== 0) throw new Error("failed to start bridge container.");
|
package/cli/src/dev.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// muscat-pk dev — run the Socket.IO bridge (Docker), dev:ui, and dev:back together.
|
|
2
2
|
import { runDevUi } from "./devUi.mjs";
|
|
3
|
-
import { runDevBack } from "./devBack.mjs";
|
|
3
|
+
import { runDevBack, stopDevBackContainers } from "./devBack.mjs";
|
|
4
4
|
import { startBridge, stopBridge, BRIDGE_CONTAINER, BRIDGE_PORT } from "./bridge.mjs";
|
|
5
5
|
import { assertManifestPorts } from "./manifest.mjs";
|
|
6
6
|
import { formatPortRanges } from "./ports.mjs";
|
|
@@ -31,7 +31,12 @@ export async function runDev(args = []) {
|
|
|
31
31
|
process.env.MUSCAT_PK_BRIDGE_CONTAINER = BRIDGE_CONTAINER;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
process.env.MUSCAT_PK_MANAGED_DEV = "1";
|
|
35
|
+
|
|
36
|
+
const cleanup = () => {
|
|
37
|
+
stopDevBackContainers();
|
|
38
|
+
if (bridgeStarted) stopBridge();
|
|
39
|
+
};
|
|
35
40
|
process.once("SIGINT", cleanup);
|
|
36
41
|
process.once("SIGTERM", cleanup);
|
|
37
42
|
process.once("exit", cleanup);
|
package/cli/src/devBack.mjs
CHANGED
|
@@ -34,6 +34,22 @@ import {
|
|
|
34
34
|
ensureImage as cppEnsureImage,
|
|
35
35
|
} from "./cpp.mjs";
|
|
36
36
|
|
|
37
|
+
const MANAGED_DEV_ENV = "MUSCAT_PK_MANAGED_DEV";
|
|
38
|
+
|
|
39
|
+
function exitAfterCleanup(code = 0) {
|
|
40
|
+
if (process.env[MANAGED_DEV_ENV] !== "1") process.exit(code ?? 0);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function stopDevBackContainers() {
|
|
44
|
+
for (const container of [
|
|
45
|
+
`${PYTHON_DEV_IMAGE}-run`,
|
|
46
|
+
`${ROS2_DEV_IMAGE}-run`,
|
|
47
|
+
`${CPP_DEV_IMAGE}-run`,
|
|
48
|
+
]) {
|
|
49
|
+
spawnSync("docker", ["rm", "-f", container], { stdio: "ignore" });
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
37
53
|
// ── IDE tooling venv (best-effort, non-blocking) ────────────────────────────
|
|
38
54
|
// `muscat-pk new` already creates this up front (see new.mjs); this just
|
|
39
55
|
// refreshes it on every `dev`/`dev:back` in case requirements.txt changed.
|
|
@@ -72,6 +88,9 @@ async function runPython(root, portRanges) {
|
|
|
72
88
|
// bridge (set by `muscat-pk dev`). Standalone dev:back has no bridge to join.
|
|
73
89
|
const bridgeContainer = process.env.MUSCAT_PK_BRIDGE_CONTAINER;
|
|
74
90
|
const netFlags = bridgeContainer ? ["--network", `container:${bridgeContainer}`] : [];
|
|
91
|
+
const hostGatewayFlags = bridgeContainer
|
|
92
|
+
? []
|
|
93
|
+
: ["--add-host", "host.docker.internal:host-gateway"];
|
|
75
94
|
// Without the bridge's netns, this container is isolated — its own
|
|
76
95
|
// 127.0.0.1 (rainbow.rb_sdk's gateway default) is itself, not the host, so
|
|
77
96
|
// it can never see a gateway already running on the host (e.g. the user's
|
|
@@ -101,7 +120,7 @@ async function runPython(root, portRanges) {
|
|
|
101
120
|
["run", "-d", "--name", container, ...netFlags,
|
|
102
121
|
// host.docker.internal is automatic on Docker Desktop (macOS/Windows);
|
|
103
122
|
// this makes it resolve on Linux too, for the no-bridge gateway fallback above.
|
|
104
|
-
|
|
123
|
+
...hostGatewayFlags,
|
|
105
124
|
"-e", "PIP_ROOT_USER_ACTION=ignore",
|
|
106
125
|
"-v", `${root}:/plugin`, "-w", "/plugin", PYTHON_DEV_IMAGE, "sleep", "infinity"],
|
|
107
126
|
{ stdio: "inherit" },
|
|
@@ -130,16 +149,21 @@ async function runPython(root, portRanges) {
|
|
|
130
149
|
}
|
|
131
150
|
});
|
|
132
151
|
|
|
133
|
-
|
|
152
|
+
let cleaned = false;
|
|
153
|
+
const cleanupResources = () => {
|
|
154
|
+
if (cleaned) return;
|
|
155
|
+
cleaned = true;
|
|
134
156
|
stopPortMonitor();
|
|
135
|
-
if (!child.killed) child.kill();
|
|
157
|
+
if (!child.killed && child.exitCode === null) child.kill();
|
|
136
158
|
spawnSync("docker", ["rm", "-f", container], { stdio: "ignore" });
|
|
137
|
-
|
|
159
|
+
};
|
|
160
|
+
const cleanup = () => {
|
|
161
|
+
cleanupResources();
|
|
162
|
+
exitAfterCleanup(0);
|
|
138
163
|
};
|
|
139
164
|
child.on("exit", (code) => {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
process.exit(code ?? 0);
|
|
165
|
+
cleanupResources();
|
|
166
|
+
exitAfterCleanup(code ?? 0);
|
|
143
167
|
});
|
|
144
168
|
process.once("SIGINT", cleanup);
|
|
145
169
|
process.once("SIGTERM", cleanup);
|
|
@@ -228,7 +252,7 @@ async function runRos2(root, portRanges) {
|
|
|
228
252
|
stopPortMonitor();
|
|
229
253
|
if (child) child.kill();
|
|
230
254
|
spawnSync("docker", ["rm", "-f", container], { stdio: "ignore" });
|
|
231
|
-
|
|
255
|
+
exitAfterCleanup(0);
|
|
232
256
|
};
|
|
233
257
|
process.on("SIGINT", cleanup);
|
|
234
258
|
process.on("SIGTERM", cleanup);
|
|
@@ -304,7 +328,7 @@ async function runCpp(root, portRanges) {
|
|
|
304
328
|
stopPortMonitor();
|
|
305
329
|
if (child) child.kill();
|
|
306
330
|
spawnSync("docker", ["rm", "-f", container], { stdio: "ignore" });
|
|
307
|
-
|
|
331
|
+
exitAfterCleanup(0);
|
|
308
332
|
};
|
|
309
333
|
process.on("SIGINT", cleanup);
|
|
310
334
|
process.on("SIGTERM", cleanup);
|
package/cli/src/devUi.mjs
CHANGED
|
@@ -211,13 +211,19 @@ export async function runDevUi(args = []) {
|
|
|
211
211
|
{ stdio: "inherit" },
|
|
212
212
|
);
|
|
213
213
|
|
|
214
|
+
let cleaned = false;
|
|
214
215
|
const cleanup = () => {
|
|
215
|
-
if (
|
|
216
|
-
|
|
216
|
+
if (cleaned) return;
|
|
217
|
+
cleaned = true;
|
|
218
|
+
if (viteProc && !viteProc.killed && viteProc.exitCode === null) viteProc.kill();
|
|
219
|
+
if (!child.killed && child.exitCode === null) child.kill();
|
|
217
220
|
};
|
|
218
221
|
process.once("SIGINT", cleanup);
|
|
219
222
|
process.once("SIGTERM", cleanup);
|
|
220
|
-
child.on("exit", (code) =>
|
|
223
|
+
child.on("exit", (code) => {
|
|
224
|
+
cleanup();
|
|
225
|
+
process.exit(code ?? 0);
|
|
226
|
+
});
|
|
221
227
|
}
|
|
222
228
|
|
|
223
229
|
export { findPluginRoot, findPreviewHostRoot };
|
package/cli/src/new.mjs
CHANGED
|
@@ -148,7 +148,7 @@ export async function runNew(args) {
|
|
|
148
148
|
|
|
149
149
|
let type = opts.type;
|
|
150
150
|
if (!type && !opts.yes) {
|
|
151
|
-
console.log("\
|
|
151
|
+
console.log("\nSelect the plugin type:");
|
|
152
152
|
console.log(" 1) Python");
|
|
153
153
|
console.log(" 2) C++");
|
|
154
154
|
console.log(" 3) ROS2 (rclpy / Python)");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"generatedAt":
|
|
1
|
+
{"generatedAt":1783639482772,"userSince":1750932757926,"hasCustomBabel":false,"hasCustomWebpack":false,"hasStaticDirs":false,"hasStorybookEslint":true,"refCount":0,"testPackages":{"@vitest/browser":"3.2.4","@vitest/coverage-v8":"3.2.4","playwright":"1.59.1","vitest":"3.2.4"},"hasRouterPackage":false,"monorepo":"Turborepo","packageManager":{"type":"yarn","version":"berry","agent":"yarn@berry"},"preview":{"usesGlobals":false},"framework":{"name":"@storybook/react-vite","options":{}},"builder":"@storybook/builder-vite","renderer":"@storybook/react","portableStoriesFileCount":0,"applicationFileCount":0,"storybookVersion":"8.6.18","storybookVersionSpecifier":"^8.6.4","language":"typescript","storybookPackages":{"@chromatic-com/storybook":{"version":"3.2.7"},"@storybook/addon-essentials":{"version":"8.6.18"},"@storybook/addon-links":{"version":"8.6.18"},"@storybook/addon-onboarding":{"version":"8.6.18"},"@storybook/addon-themes":{"version":"8.6.18"},"@storybook/blocks":{"version":"8.6.18"},"@storybook/experimental-addon-test":{"version":"8.6.18"},"@storybook/react":{"version":"8.6.18"},"@storybook/react-vite":{"version":"8.6.18"},"@storybook/test":{"version":"8.6.18"},"@storybook/theming":{"version":"8.6.18"},"eslint-plugin-storybook":{"version":"0.11.6"},"storybook":{"version":"8.6.18"},"storybook-addon-react-docgen":{"version":"1.2.44"}},"addons":{"$SNIP/node_modules/@storybook/addon-links":{"version":null},"$SNIP/node_modules/@storybook/addon-essentials":{"version":null},"$SNIP/node_modules/@chromatic-com/storybook":{"version":null},"$SNIP/node_modules/@storybook/addon-themes":{"version":null},"$SNIP/node_modules/@storybook/experimental-addon-test":{"version":null}}}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rainbow-robotics/muscat-plugin-kit",
|
|
3
|
-
"version": "0.1.2-dev.
|
|
3
|
+
"version": "0.1.2-dev.50",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=20"
|
|
@@ -53,8 +53,8 @@
|
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
55
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
56
|
-
"@rainbow-robotics/plugin-ui": "0.1.2-dev.
|
|
57
|
-
"@rainbow-robotics/preview-host": "0.1.2-dev.
|
|
56
|
+
"@rainbow-robotics/plugin-ui": "0.1.2-dev.50",
|
|
57
|
+
"@rainbow-robotics/preview-host": "0.1.2-dev.50",
|
|
58
58
|
"postcss": "^8.5.8",
|
|
59
59
|
"socket.io": "^4.8.1",
|
|
60
60
|
"typescript": "^5.8.0",
|