@rainbow-robotics/muscat-plugin-kit 1.3.6-dev.0 → 1.3.6-dev.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.
@@ -35,6 +35,11 @@ function readVersion(binPath) {
35
35
 
36
36
  const isBinaryMode = typeof Bun !== "undefined";
37
37
 
38
+ // 바이너리에는 package.json 이 없다 — 컴파일 시 임베드한 버전을 쓴다.
39
+ if (isBinaryMode && !process.env.MUSCAT_PK_VERSION) {
40
+ process.env.MUSCAT_PK_VERSION = (await import("../src/templates-embedded.mjs")).KIT_VERSION;
41
+ }
42
+
38
43
  (function delegateToLocalInstall() {
39
44
  try {
40
45
  const localBin = resolveLocalCliBin();
@@ -2,7 +2,7 @@
2
2
  // Pre-build step: serialise cli/templates/** into cli/src/templates-embedded.mjs
3
3
  // so that `bun build --compile` can embed them without needing the filesystem.
4
4
  import { readdirSync, readFileSync, writeFileSync, statSync } from "node:fs";
5
- import { resolve, relative } from "node:path";
5
+ import { resolve } from "node:path";
6
6
  import { fileURLToPath } from "node:url";
7
7
 
8
8
  const root = resolve(fileURLToPath(import.meta.url), "..");
@@ -19,10 +19,15 @@ function walk(baseDir, prefix) {
19
19
  }
20
20
  walk(resolve(root, "templates") + "/", "");
21
21
  walk(resolve(root, "docker") + "/", "docker/");
22
+ // Dockerfile.bridge 의 COPY 대상
23
+ files["src/socketBridge.mjs"] = readFileSync(resolve(root, "src/socketBridge.mjs"), "base64");
24
+
25
+ const { version } = JSON.parse(readFileSync(resolve(root, "../package.json"), "utf8"));
22
26
 
23
27
  writeFileSync(out,
24
28
  `// AUTO-GENERATED by cli/bundle-templates.mjs — do not edit.\n` +
25
29
  `// ponytail: generated at publish time; not tracked in git.\n` +
30
+ `export const KIT_VERSION = ${JSON.stringify(version)};\n` +
26
31
  `export const TEMPLATES = ${JSON.stringify(files)};\n`
27
32
  );
28
33
  console.log(`bundled ${Object.keys(files).length} template files → src/templates-embedded.mjs`);
@@ -5,8 +5,9 @@
5
5
  // it at localhost:10000 too — no host.docker.internal needed (robust cross-OS).
6
6
  import { spawnSync } from "node:child_process";
7
7
  import { createServer, connect } from "node:net";
8
- import { existsSync } from "node:fs";
9
- import { resolve } from "node:path";
8
+ import { existsSync, mkdirSync, writeFileSync } from "node:fs";
9
+ import { tmpdir } from "node:os";
10
+ import { dirname, resolve } from "node:path";
10
11
  import { canSkipImageBuild, hasBin, kitRoot, log, pruneMuskatImages } from "./util.mjs";
11
12
  import { MEDIA_PORTS, mediaPortFlags } from "./ports.mjs";
12
13
  import { usesHostNetwork } from "./zenohDev.mjs";
@@ -15,16 +16,30 @@ export const BRIDGE_IMAGE = "muscat-pk-bridge";
15
16
  export const BRIDGE_CONTAINER = "muscat-pk-bridge-run";
16
17
  export const BRIDGE_PORT = 10000;
17
18
 
18
- const DOCKERFILE = resolve(kitRoot, "cli/docker/Dockerfile.bridge");
19
- const BUILD_CONTEXT = resolve(kitRoot, "cli");
19
+ // 컴파일된 바이너리에는 cli/ 트리가 없어 임베드 스냅샷에서 build context 를 tmp 에 복원한다.
20
+ const BRIDGE_CONTEXT_FILES = ["docker/Dockerfile.bridge", "docker/bridge-package.json", "src/socketBridge.mjs"];
21
+
22
+ async function resolveBridgeContext() {
23
+ const context = resolve(kitRoot, "cli");
24
+ const dockerfile = resolve(context, "docker/Dockerfile.bridge");
25
+ if (existsSync(dockerfile)) return { dockerfile, context };
26
+
27
+ const { TEMPLATES } = await import("./templates-embedded.mjs");
28
+ const dir = resolve(tmpdir(), "muscat-pk-bridge-context");
29
+ for (const key of BRIDGE_CONTEXT_FILES) {
30
+ const b64 = TEMPLATES[key];
31
+ if (!b64) throw new Error(`Embedded file missing: ${key}. Reinstall muscat-plugin-kit.`);
32
+ const file = resolve(dir, key);
33
+ mkdirSync(dirname(file), { recursive: true });
34
+ writeFileSync(file, Buffer.from(b64, "base64"));
35
+ }
36
+ return { dockerfile: resolve(dir, "docker/Dockerfile.bridge"), context: dir };
37
+ }
20
38
 
21
39
  function assertDockerReady() {
22
40
  if (!hasBin("docker")) {
23
41
  throw new Error("Docker not found. `muscat-pk dev` runs the Socket.IO bridge in a container.");
24
42
  }
25
- if (!existsSync(DOCKERFILE)) {
26
- throw new Error(`kit Dockerfile missing at ${DOCKERFILE} (reinstall muscat-plugin-kit).`);
27
- }
28
43
  }
29
44
 
30
45
  // Is a host TCP port already bound? (Catches another bridge or a stray process.)
@@ -54,13 +69,14 @@ function waitForPort(port, timeoutMs = 15_000) {
54
69
  });
55
70
  }
56
71
 
57
- function ensureImage() {
72
+ async function ensureImage() {
58
73
  if (canSkipImageBuild(BRIDGE_IMAGE)) {
59
74
  log.step(`${BRIDGE_IMAGE} already built — skipping docker build`);
60
75
  return;
61
76
  }
77
+ const { dockerfile, context } = await resolveBridgeContext();
62
78
  log.step(`docker build -t ${BRIDGE_IMAGE} (first run is slow, then cached)…`);
63
- const r = spawnSync("docker", ["build", "-t", BRIDGE_IMAGE, "-f", DOCKERFILE, BUILD_CONTEXT], { stdio: "inherit" });
79
+ const r = spawnSync("docker", ["build", "-t", BRIDGE_IMAGE, "-f", dockerfile, context], { stdio: "inherit" });
64
80
  if (r.status !== 0) throw new Error("docker build failed (bridge image).");
65
81
  pruneMuskatImages();
66
82
  }
@@ -104,7 +120,7 @@ export async function startBridge({ zenohPort = null, pluginPorts = [] } = {}) {
104
120
  const media = mediaBusy.length === 0;
105
121
  if (!media) log.warn(`MediaMTX port(s) already in use: ${mediaBusy.join(", ")} — video streaming disabled in dev.`);
106
122
 
107
- ensureImage();
123
+ await ensureImage();
108
124
 
109
125
  log.step("starting Socket.IO bridge container…");
110
126
  // The backend joins THIS container's netns (--network container:), and a
package/cli/src/util.mjs CHANGED
@@ -317,6 +317,7 @@ export async function resolveDockerfile(name) {
317
317
 
318
318
  /** This kit's installed version (from its package.json). */
319
319
  export function kitVersion() {
320
+ if (process.env.MUSCAT_PK_VERSION) return process.env.MUSCAT_PK_VERSION;
320
321
  try {
321
322
  return JSON.parse(readFileSync(resolve(kitRoot, "package.json"), "utf8"))
322
323
  .version;
@@ -1 +1 @@
1
- {"generatedAt":1791426431592,"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":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}}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rainbow-robotics/muscat-plugin-kit",
3
- "version": "1.3.6-dev.0",
3
+ "version": "1.3.6-dev.2",
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.0",
57
- "@rainbow-robotics/preview-host": "1.3.6-dev.0",
56
+ "@rainbow-robotics/plugin-ui": "1.3.6-dev.2",
57
+ "@rainbow-robotics/preview-host": "1.3.6-dev.2",
58
58
  "postcss": "^8.5.8",
59
59
  "socket.io": "^4.8.1",
60
60
  "typescript": "^5.8.0",