@rainbow-robotics/muscat-plugin-kit 0.1.2-dev.13 → 0.1.2-dev.15

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.
@@ -30,6 +30,7 @@ function isNativeMissing(err) {
30
30
  return (
31
31
  msg.includes("another platform") ||
32
32
  msg.includes("Cannot find module") ||
33
+ msg.includes("Cannot find package") ||
33
34
  msg.includes("not found") ||
34
35
  msg.includes("No such file") ||
35
36
  msg.includes("ENOENT") ||
@@ -1,52 +1,170 @@
1
- // muscat-pk update — update the JS plugin kit and host-provided UI contract.
2
- import { execSync } from "node:child_process";
3
- import { existsSync, readFileSync } from "node:fs";
4
- import { resolve } from "node:path";
5
- import { findPluginRoot, KIT_PUBLISHED_NAME, log, parseArgs } from "./util.mjs";
1
+ // muscat-pk update — update the CLI itself AND the plugin project's JS deps.
2
+ //
3
+ // Three install modes are handled:
4
+ // binary : Bun self-contained binary downloaded from S3
5
+ // → re-download from S3, replace process.execPath
6
+ // npm -g : globally installed Node.js package
7
+ // → npm install -g @rainbow-robotics/muscat-plugin-kit@<tag>
8
+ // local : plugin project's node_modules (fallback)
9
+ // → <pm> add @rainbow-robotics/muscat-plugin-kit@<tag>
10
+ //
11
+ // After updating the CLI itself, also bumps the plugin project's local deps.
12
+ import { execSync, spawn } from "node:child_process";
13
+ import { chmodSync, copyFileSync, existsSync, readFileSync, writeFileSync } from "node:fs";
14
+ import { tmpdir } from "node:os";
15
+ import { join, resolve } from "node:path";
16
+ import { findPluginRoot, KIT_PUBLISHED_NAME, kitVersion, log, parseArgs } from "./util.mjs";
6
17
 
7
18
  const PLUGIN_UI_PACKAGE = "@rainbow-robotics/plugin-ui";
19
+ const S3_BASE = "https://rainbow-deploy.s3.ap-northeast-2.amazonaws.com/muscat-plugin-kit";
20
+
21
+ const isBinaryMode = typeof Bun !== "undefined";
22
+
23
+ // ── helpers ───────────────────────────────────────────────────────────────────
8
24
 
9
25
  function detectPm(root) {
10
26
  try {
11
27
  const pkg = JSON.parse(readFileSync(resolve(root, "package.json"), "utf8"));
12
28
  if (pkg.packageManager) return pkg.packageManager.split("@")[0];
13
- } catch {
14
- /* ignore */
15
- }
29
+ } catch { /* ignore */ }
16
30
  if (existsSync(resolve(root, "pnpm-lock.yaml"))) return "pnpm";
17
31
  if (existsSync(resolve(root, "yarn.lock"))) return "yarn";
18
32
  if (existsSync(resolve(root, "bun.lockb"))) return "bun";
19
33
  return "npm";
20
34
  }
21
35
 
22
- export async function runUpdate(args = []) {
23
- const root = findPluginRoot();
24
- const pm = detectPm(root);
25
- const opts = parseArgs(args);
36
+ async function fetchText(url) {
37
+ const res = await fetch(url);
38
+ if (!res.ok) throw new Error(`HTTP ${res.status}: ${url}`);
39
+ return (await res.text()).trim();
40
+ }
41
+
42
+ async function fetchBinary(url) {
43
+ const res = await fetch(url);
44
+ if (!res.ok) throw new Error(`HTTP ${res.status}: ${url}`);
45
+ return Buffer.from(await res.arrayBuffer());
46
+ }
47
+
48
+ function s3BinaryName() {
49
+ const platform = process.platform;
50
+ const arch = process.arch;
51
+ const plat = platform === "win32" ? "win" : platform === "darwin" ? "darwin" : "linux";
52
+ const cpu = arch === "arm64" ? "arm64" : "x64";
53
+ const ext = platform === "win32" ? ".exe" : "";
54
+ return `muscat-pk-${plat}-${cpu}${ext}`;
55
+ }
56
+
57
+ async function resolveS3Version(tag) {
58
+ const pointer = tag === "dev" ? "dev-version.txt" : "latest-version.txt";
59
+ return fetchText(`${S3_BASE}/${pointer}`);
60
+ }
61
+
62
+ // ── self-update: binary ───────────────────────────────────────────────────────
63
+
64
+ async function updateBinary(tag) {
65
+ const version = await resolveS3Version(tag);
66
+ const current = kitVersion();
67
+ if (version === current) {
68
+ log.ok(`이미 최신 버전입니다 (v${current})`);
69
+ return;
70
+ }
71
+
72
+ const binaryName = s3BinaryName();
73
+ const url = `${S3_BASE}/v${version}/${binaryName}`;
74
+ log.step(`바이너리 다운로드: v${current} → v${version}`);
75
+
76
+ const data = await fetchBinary(url);
77
+ const execPath = process.execPath;
78
+
79
+ if (process.platform === "win32") {
80
+ // Windows: cannot overwrite a running .exe — write .new then schedule replacement
81
+ const newPath = execPath + ".new";
82
+ writeFileSync(newPath, data);
26
83
 
27
- const range =
28
- opts._[0] ||
29
- opts.version ||
30
- opts["muscat-plugin-kit"] ||
31
- opts["plugin-ui"] ||
32
- "latest";
33
- const list = [
34
- `${KIT_PUBLISHED_NAME}@${range}`,
35
- `${PLUGIN_UI_PACKAGE}@${range}`,
36
- ];
84
+ // PowerShell snippet that waits for this process to exit, then renames
85
+ const ps = `Start-Sleep -Milliseconds 500; Move-Item -Force '${newPath}' '${execPath}'`;
86
+ spawn("powershell", ["-NoProfile", "-Command", ps], {
87
+ detached: true,
88
+ stdio: "ignore",
89
+ }).unref();
37
90
 
91
+ log.ok(`v${version} 다운로드 완료. 다음 실행 시 자동 적용됩니다.`);
92
+ } else {
93
+ // macOS / Linux: can replace the file while it's mapped into memory
94
+ const tmp = join(tmpdir(), `muscat-pk-${version}`);
95
+ writeFileSync(tmp, data);
96
+ chmodSync(tmp, 0o755);
97
+ copyFileSync(tmp, execPath);
98
+ log.ok(`v${version} 업데이트 완료.`);
99
+ }
100
+ }
101
+
102
+ // ── self-update: npm global ───────────────────────────────────────────────────
103
+
104
+ function updateNpmGlobal(tag) {
105
+ log.step(`npm install -g ${KIT_PUBLISHED_NAME}@${tag}`);
106
+ execSync(`npm install -g ${KIT_PUBLISHED_NAME}@${tag}`, { stdio: "inherit" });
107
+ log.ok("글로벌 CLI 업데이트 완료.");
108
+ }
109
+
110
+ // ── plugin project local deps ─────────────────────────────────────────────────
111
+
112
+ function updateLocalDeps(root, tag) {
113
+ const pm = detectPm(root);
114
+ const list = [`${KIT_PUBLISHED_NAME}@${tag}`, `${PLUGIN_UI_PACKAGE}@${tag}`];
38
115
  const cmd =
39
- pm === "npm"
40
- ? `npm install ${list.join(" ")}`
41
- : pm === "yarn"
42
- ? `yarn add ${list.join(" ")}`
43
- : `${pm} add ${list.join(" ")}`;
116
+ pm === "npm" ? `npm install ${list.join(" ")}`
117
+ : pm === "yarn" ? `yarn add ${list.join(" ")}`
118
+ : `${pm} add ${list.join(" ")}`;
44
119
 
45
- log.step(`${pm}: ${list.join(", ")}`);
120
+ log.step(`플러그인 로컬 deps 업데이트 (${pm}): ${list.join(", ")}`);
46
121
  try {
47
122
  execSync(cmd, { cwd: root, stdio: "inherit" });
48
- log.ok("kit packages updated");
123
+ log.ok("로컬 deps 업데이트 완료.");
124
+ } catch {
125
+ log.warn("로컬 deps 업데이트 실패 (오프라인?). 수동 실행:\n " + cmd);
126
+ }
127
+ }
128
+
129
+ // ── main ─────────────────────────────────────────────────────────────────────
130
+
131
+ export async function runUpdate(args = []) {
132
+ const opts = parseArgs(args);
133
+ const tag = opts._[0] || opts.version || opts.tag || "latest";
134
+
135
+ // 1. Update the CLI itself
136
+ if (isBinaryMode) {
137
+ log.step("바이너리 자기 업데이트 중…");
138
+ try {
139
+ await updateBinary(tag);
140
+ } catch (err) {
141
+ log.warn(`바이너리 업데이트 실패: ${err.message}`);
142
+ }
143
+ } else {
144
+ // Check if globally installed via npm (execPath's npm prefix contains this package)
145
+ const isGlobal = (() => {
146
+ try {
147
+ const prefix = execSync("npm prefix -g", { encoding: "utf8" }).trim();
148
+ const globalBin = join(prefix, "bin", "muscat-pk");
149
+ const globalBinCmd = join(prefix, "bin", "muscat-pk.cmd");
150
+ return existsSync(globalBin) || existsSync(globalBinCmd);
151
+ } catch { return false; }
152
+ })();
153
+
154
+ if (isGlobal) {
155
+ try {
156
+ updateNpmGlobal(tag);
157
+ } catch (err) {
158
+ log.warn(`글로벌 CLI 업데이트 실패: ${err.message}`);
159
+ }
160
+ }
161
+ }
162
+
163
+ // 2. Update the plugin project's local deps (best-effort)
164
+ try {
165
+ const root = findPluginRoot();
166
+ updateLocalDeps(root, tag);
49
167
  } catch {
50
- log.warn("update failed (offline?). Run manually:\n " + cmd);
168
+ // Not inside a plugin project — skip local update silently
51
169
  }
52
170
  }
@@ -1,3 +1,3 @@
1
- rainbow-rb-sdk
2
- rainbow-rb-flat-buffers
3
- python-socketio[aiohttp]
1
+ rainbow-rb-sdk==0.0.9.dev40
2
+ rainbow-rb-flat-buffers==0.0.9.dev40
3
+ rainbow-rb-zenoh==0.0.9.dev40
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rainbow-robotics/muscat-plugin-kit",
3
- "version": "0.1.2-dev.13",
3
+ "version": "0.1.2-dev.15",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": ">=20"
@@ -31,10 +31,10 @@
31
31
  "@types/react-dom": "^19.0.4"
32
32
  },
33
33
  "dependencies": {
34
- "@rainbow-robotics/preview-host": "0.1.2-dev.13",
34
+ "@rainbow-robotics/preview-host": "workspace:*",
35
35
  "socket.io": "^4.8.1"
36
36
  },
37
37
  "optionalDependencies": {
38
38
  "esbuild-wasm": "^0.25.0"
39
39
  }
40
- }
40
+ }
@@ -1,3 +0,0 @@
1
- {
2
- "typescript.tsdk": "node_modules/typescript/lib"
3
- }