@rainbow-robotics/muscat-plugin-kit 1.3.6-dev.2 → 1.3.6-dev.4

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.
@@ -11,7 +11,7 @@ import { spawn, spawnSync } from "node:child_process";
11
11
  import { existsSync, mkdirSync, readFileSync, watch, writeFileSync } from "node:fs";
12
12
  import { isIP } from "node:net";
13
13
  import { dirname, resolve } from "node:path";
14
- import { ensureDocker, ensureIdeVenv, findPluginRoot, log, promptRobotConnection, realtimeFlags } from "./util.mjs";
14
+ import { dockerUserFlags, ensureDocker, ensureIdeVenv, findPluginRoot, log, promptRobotConnection, realtimeFlags } from "./util.mjs";
15
15
  import { ensureRemoteZenohEnv, usesHostNetwork } from "./zenohDev.mjs";
16
16
  import { PLUGIN_ID_RE, assertManifestPorts, assertManifestVariables, manifestRuntime, readManifest, rosNamespace, validateManifest } from "./manifest.mjs";
17
17
  import {
@@ -184,11 +184,12 @@ async function runPython(root, portRanges) {
184
184
  const docker = (args, opts = {}) =>
185
185
  spawnSync("docker", args, { cwd: root, stdio: "inherit", ...opts });
186
186
 
187
- // start a warm, long-lived container with the plugin mounted
187
+ // start a warm, long-lived container with the plugin mounted.
188
+ // 호스트 uid 로 돌린다(dockerUserFlags) — root 로 쓴 build/·install/ 은 사용자가 지우지 못한다.
188
189
  docker(["rm", "-f", container], { stdio: "ignore" });
189
190
  log.step("starting Python dev container…");
190
191
  const up = docker(
191
- ["run", "-d", "--name", container, ...net.run, ...standaloneZenohPortFlags, ...realtimeFlags(),
192
+ ["run", "-d", "--name", container, ...net.run, ...standaloneZenohPortFlags, ...realtimeFlags(), ...dockerUserFlags(),
192
193
  "-e", "PIP_ROOT_USER_ACTION=ignore",
193
194
  "-v", `${root}:/plugin`, "-w", "/plugin", PYTHON_DEV_IMAGE, "sleep", "infinity"],
194
195
  { stdio: "inherit" },
@@ -488,7 +489,7 @@ async function runRos2(root, portRanges) {
488
489
  docker(["rm", "-f", container], { stdio: "ignore" });
489
490
  log.step("starting ROS2 dev container…");
490
491
  const up = docker(
491
- ["run", "-d", "--name", container, ...net.run, ...realtimeFlags(), "-e", "PIP_ROOT_USER_ACTION=ignore", "-v", `${root}:/plugin`, "-w", "/plugin", ROS2_DEV_IMAGE, "sleep", "infinity"],
492
+ ["run", "-d", "--name", container, ...net.run, ...realtimeFlags(), ...dockerUserFlags(), "-e", "PIP_ROOT_USER_ACTION=ignore", "-v", `${root}:/plugin`, "-w", "/plugin", ROS2_DEV_IMAGE, "sleep", "infinity"],
492
493
  { stdio: "inherit" },
493
494
  );
494
495
  if (up.status !== 0) throw new Error("failed to start dev container.");
@@ -581,7 +582,7 @@ async function runCpp(root, portRanges) {
581
582
  docker(["rm", "-f", container], { stdio: "ignore" });
582
583
  log.step("starting C++ dev container…");
583
584
  const up = docker(
584
- ["run", "-d", "--name", container, ...net.run, ...realtimeFlags(), "-v", `${root}:/plugin`, "-w", "/plugin", CPP_DEV_IMAGE, "sleep", "infinity"],
585
+ ["run", "-d", "--name", container, ...net.run, ...realtimeFlags(), ...dockerUserFlags(), "-v", `${root}:/plugin`, "-w", "/plugin", CPP_DEV_IMAGE, "sleep", "infinity"],
585
586
  { stdio: "inherit" },
586
587
  );
587
588
  if (up.status !== 0) throw new Error("failed to start dev container.");
package/cli/src/new.mjs CHANGED
@@ -87,6 +87,7 @@ export function runtimeForChoice(choice, slug) {
87
87
 
88
88
  export function applyTokens(dir, tokens) {
89
89
  for (const entry of readdirSync(dir)) {
90
+ if (entry === "node_modules" || entry === ".git" || entry === ".venv") continue;
90
91
  const full = resolve(dir, entry);
91
92
  if (statSync(full).isDirectory()) {
92
93
  applyTokens(full, tokens);
package/cli/src/ros2.mjs CHANGED
@@ -3,7 +3,7 @@
3
3
  import { spawnSync } from "node:child_process";
4
4
  import { existsSync, readdirSync } from "node:fs";
5
5
  import { dirname, resolve } from "node:path";
6
- import { canSkipImageBuild, imageKey, imageKeyLabel, hasBin, log, pruneMuskatImages, resolveDockerfile } from "./util.mjs";
6
+ import { canSkipImageBuild, imageKey, imageKeyLabel, dockerUserFlags, hasBin, log, pruneMuskatImages, resolveDockerfile } from "./util.mjs";
7
7
 
8
8
  export const ROS2_DEV_IMAGE = "muscat-pk-ros2-dev";
9
9
 
@@ -94,7 +94,8 @@ export function colconBuild(root, { image = ROS2_DEV_IMAGE, symlink = false, arc
94
94
  const platformFlags = dockerPlatform ? ["--platform", dockerPlatform] : [];
95
95
  const r = spawnSync(
96
96
  "docker",
97
- ["run", "--rm", ...platformFlags, "-e", "PIP_ROOT_USER_ACTION=ignore", "-v", `${root}:/plugin`, "-w", "/plugin", actualImage, "bash", "-lc", script],
97
+ // python/cpp 와 같이 호스트 uid 로 돌린다 — root 소유 산출물이 남으면 사용자가 지우지 못한다.
98
+ ["run", "--rm", ...platformFlags, ...dockerUserFlags(), "-e", "PIP_ROOT_USER_ACTION=ignore", "-v", `${root}:/plugin`, "-w", "/plugin", actualImage, "bash", "-lc", script],
98
99
  { cwd: root, stdio: "inherit" },
99
100
  );
100
101
  if (r.status !== 0) throw new Error(`colcon build failed${arch ? ` (${arch})` : ""}.`);
package/cli/src/type.mjs CHANGED
@@ -94,7 +94,7 @@ export async function runType(args) {
94
94
  } else {
95
95
  log.step(`adding ros2_ws/ overlay (${runtimeChoice.rosClient})`);
96
96
  await overlayRos2(root, slug, runtimeChoice.rosClient);
97
- applyTokens(root, {
97
+ applyTokens(resolve(root, "ros2_ws"), {
98
98
  __PLUGIN_ID__: pluginId,
99
99
  __PLUGIN_NAME__: pluginName,
100
100
  __PLUGIN_SLUG__: slug,
@@ -108,7 +108,7 @@ export async function runType(args) {
108
108
  } else {
109
109
  log.step("adding cpp/ overlay");
110
110
  await overlayCpp(root);
111
- applyTokens(root, {
111
+ applyTokens(resolve(root, "cpp"), {
112
112
  __PLUGIN_ID__: pluginId,
113
113
  __PLUGIN_NAME__: pluginName,
114
114
  __PLUGIN_SLUG__: slug,
@@ -1 +1 @@
1
- {"generatedAt":1791428163529,"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}}}
1
+ {"generatedAt":1791432235198,"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": "1.3.6-dev.2",
3
+ "version": "1.3.6-dev.4",
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": "1.3.6-dev.2",
57
- "@rainbow-robotics/preview-host": "1.3.6-dev.2",
56
+ "@rainbow-robotics/plugin-ui": "1.3.6-dev.4",
57
+ "@rainbow-robotics/preview-host": "1.3.6-dev.4",
58
58
  "postcss": "^8.5.8",
59
59
  "socket.io": "^4.8.1",
60
60
  "typescript": "^5.8.0",