@rainbow-robotics/muscat-plugin-kit 1.10.3 → 1.10.4-dev.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.ko.md +4 -5
- package/README.md +4 -5
- package/cli/bin/muscat-pk.mjs +1 -1
- package/cli/src/dev.mjs +2 -0
- package/cli/src/devBack.mjs +24 -0
- package/cli/src/sim.mjs +1 -2
- package/cli/storybook-dist/project.json +1 -1
- package/package.json +3 -3
package/README.ko.md
CHANGED
|
@@ -169,7 +169,7 @@ muscat-pk dev:back [--robot-ip <ip>] [--robot-token <token>] [--keep-id]
|
|
|
169
169
|
|
|
170
170
|
| 명령 | 실행되는 것 |
|
|
171
171
|
|---|---|
|
|
172
|
-
| `dev` | 로봇이 없거나 로봇에 Muscat이 없으면 로컬 Muscat 런타임, 그리고 `dev:ui` + `dev:back` |
|
|
172
|
+
| `dev` | 먼저 dev 이미지와 백엔드를 빌드하고(빌드 실패는 경고만), 로봇이 없거나 로봇에 Muscat이 없으면 로컬 Muscat 런타임, 그리고 `dev:ui` + `dev:back` |
|
|
173
173
|
| `dev:ui` | 플러그인 Vite 개발 서버 + preview-host `http://localhost:4180` (사용 중이면 다음 빈 포트). 브라우저로 엶 |
|
|
174
174
|
| `dev:back` | 로봇 환경과 같은 Docker 컨테이너에서 백엔드 실행. Python은 `py/**/*.py`가 바뀌면 재시작 (watchfiles) |
|
|
175
175
|
|
|
@@ -201,12 +201,12 @@ muscat-pk dev --sim rby1-m_v1.2
|
|
|
201
201
|
|
|
202
202
|
| `--sim` | 함께 뜨는 Muscat 서비스 | 시뮬레이터 |
|
|
203
203
|
|---|---|---|
|
|
204
|
-
| `
|
|
204
|
+
| `500920` | common, log, manipulate | `rainbowroboticsofficial/cobot-sim` 1개 |
|
|
205
205
|
| `RBY2` | common, log, manipulate | cobot-sim 3개 (C500880, C501880, C502880) |
|
|
206
206
|
| `rby1-a`, `rby1-m`, `rby1-ub` (`rby1-m_v1.2`처럼 버전 지정 가능) | common, log, rby1 | `rainbowroboticsofficial/rby1-sim` + Xvfb (로컬 빌드) |
|
|
207
207
|
|
|
208
|
-
- 시뮬레이터 기종이 로컬 Muscat의 로봇 모델로 등록됩니다(`
|
|
209
|
-
- 시뮬레이터는 `--sim`을 줄 때만 뜹니다. 그 밖의 값이면 `--sim takes one of:
|
|
208
|
+
- 시뮬레이터 기종이 로컬 Muscat의 로봇 모델로 등록됩니다(`500920`은 C500920, `rby1-m`은 m). UI는 mock 프리뷰가 아니라 실제 Muscat 화면(대시보드, 컴포넌트, Move, Log, Settings)으로 뜹니다.
|
|
209
|
+
- 시뮬레이터는 `--sim`을 줄 때만 뜹니다. 그 밖의 값이면 `--sim takes one of: 500920, RBY2, rby1-a, rby1-m, rby1-ub (rby1 also takes rby1-m_v1.2)` 오류가 납니다. manifest의 `targetModels`에 없는 기종이면 경고만 합니다.
|
|
210
210
|
- 시뮬레이터 이미지는 Docker Hub의 최신 태그를 씁니다 (rby1에 버전을 주면 그 버전 태그). 오프라인이면 이미 받아 둔 이미지를 씁니다.
|
|
211
211
|
- rby1-sim은 화면을 계속 렌더링하므로 CPU를 1코어 정도 씁니다. 상한은 `MUSCAT_PK_RBY1_CPUS`(기본 1.5)입니다.
|
|
212
212
|
- `muscat-dev` 같은 다른 Muscat이 떠 있으면 시뮬레이터를 붙이지 않습니다.
|
|
@@ -577,7 +577,6 @@ if (await rb.confirm({ title: "실행", message: "백엔드 동작을 시작할
|
|
|
577
577
|
| `rb.program.getSteps(scope?)` | Program 페이지에 열린 프로그램의 메인 스텝 트리 |
|
|
578
578
|
| `rb.program.setSteps(steps, scope?)` | 메인 스텝 트리 교체. 저장되지 않은 편집으로 들어가고 사용자가 저장 |
|
|
579
579
|
| `rb.program.getCatalog(scope?)` | 로드된 로봇의 명령 카탈로그 (이름, 기본 인자, 중첩 규칙) |
|
|
580
|
-
| `rb.program.getCommandDefaults?(command, scope?)` | 기본값이 실제 로봇 상태를 읽는 명령(카탈로그 `rules.hasFactoryDataFn`)의 기본 step. 선택적이며 호스트에 따라 없을 수 있음 |
|
|
581
580
|
|
|
582
581
|
```ts
|
|
583
582
|
type PluginProgramStep = {
|
package/README.md
CHANGED
|
@@ -169,7 +169,7 @@ muscat-pk dev:back [--robot-ip <ip>] [--robot-token <token>] [--keep-id]
|
|
|
169
169
|
|
|
170
170
|
| Command | What runs |
|
|
171
171
|
|---|---|
|
|
172
|
-
| `dev` | a local Muscat runtime when no robot is given (or the robot runs no Muscat), then `dev:ui` and `dev:back` |
|
|
172
|
+
| `dev` | builds the dev image and backend first (a failed build only warns), then a local Muscat runtime when no robot is given (or the robot runs no Muscat), then `dev:ui` and `dev:back` |
|
|
173
173
|
| `dev:ui` | the plugin's Vite dev server + preview-host at `http://localhost:4180` (next free port), opened in the browser |
|
|
174
174
|
| `dev:back` | the backend in a Docker container matching the robot. Python restarts on `py/**/*.py` changes (watchfiles) |
|
|
175
175
|
|
|
@@ -201,12 +201,12 @@ muscat-pk dev --sim rby1-m_v1.2
|
|
|
201
201
|
|
|
202
202
|
| `--sim` | Muscat services | Simulator |
|
|
203
203
|
|---|---|---|
|
|
204
|
-
| `
|
|
204
|
+
| `500920` | common, log, manipulate | one `rainbowroboticsofficial/cobot-sim` |
|
|
205
205
|
| `RBY2` | common, log, manipulate | three cobot-sim (C500880, C501880, C502880) |
|
|
206
206
|
| `rby1-a`, `rby1-m`, `rby1-ub` (or a version, e.g. `rby1-m_v1.2`) | common, log, rby1 | `rainbowroboticsofficial/rby1-sim` + Xvfb, built locally |
|
|
207
207
|
|
|
208
|
-
- The simulated model is registered as the local Muscat's robot model (`
|
|
209
|
-
- A simulator runs only with `--sim`. Any other value fails with `--sim takes one of:
|
|
208
|
+
- The simulated model is registered as the local Muscat's robot model (`500920` → C500920, `rby1-m` → m). The UI is then the real Muscat UI (dashboard, components, Move, Log, Settings) instead of the mock preview.
|
|
209
|
+
- A simulator runs only with `--sim`. Any other value fails with `--sim takes one of: 500920, RBY2, rby1-a, rby1-m, rby1-ub (rby1 also takes rby1-m_v1.2)`. A model missing from the manifest's `targetModels` only gets a warning.
|
|
210
210
|
- Simulator images use the latest Docker Hub tag (an rby1 version picks the matching tag). Offline, an already pulled image is used.
|
|
211
211
|
- rby1-sim keeps rendering, so it uses about one CPU core. The cap is `MUSCAT_PK_RBY1_CPUS` (default 1.5).
|
|
212
212
|
- No simulator is attached while another Muscat such as `muscat-dev` is running.
|
|
@@ -577,7 +577,6 @@ if (await rb.confirm({ title: "Run", message: "Start the backend action?" })) {
|
|
|
577
577
|
| `rb.program.getSteps(scope?)` | main step tree of the program open on the Program page |
|
|
578
578
|
| `rb.program.setSteps(steps, scope?)` | replace it — an unsaved edit the user then saves |
|
|
579
579
|
| `rb.program.getCatalog(scope?)` | the loaded robot's command catalog (names, default args, nesting rules) |
|
|
580
|
-
| `rb.program.getCommandDefaults?(command, scope?)` | default step of a command whose defaults read the live robot (catalog `rules.hasFactoryDataFn`); optional, host-dependent |
|
|
581
580
|
|
|
582
581
|
```ts
|
|
583
582
|
type PluginProgramStep = {
|
package/cli/bin/muscat-pk.mjs
CHANGED
|
@@ -88,7 +88,7 @@ function formatHelp() {
|
|
|
88
88
|
commandRow("new [dir]", `Scaffold a new plugin project ${color.dim("(prompts: author, email, description, type, front-package-manager)")}`),
|
|
89
89
|
commandRow("type change", `Switch backend type ${color.dim("(python | cpp | ros2-python | ros2-cpp)")}`),
|
|
90
90
|
commandRow("build", `Build + lock deps + vendor wheels + zip ${color.dim(`(${option("--arch")} amd64|arm64|both)`)}`),
|
|
91
|
-
commandRow("dev", `Run a local Muscat runtime, dev:ui, and dev:back together ${color.dim(`(${option("--sim")}
|
|
91
|
+
commandRow("dev", `Run a local Muscat runtime, dev:ui, and dev:back together ${color.dim(`(${option("--sim")} 500920|RBY2|rby1-a|rby1-m|rby1-ub)`)}`),
|
|
92
92
|
commandRow("dev:ui", `Preview the plugin in a mini-Muscat ${color.dim("(preview-host)")}`),
|
|
93
93
|
commandRow("dev:back", `Run the plugin back end ${color.dim("(python: watchfiles reload / ros2: Docker)")}`),
|
|
94
94
|
commandRow("storybook", `Browse the bundled rb-components Storybook ${color.dim(`(${option("--port")} <n>, ${option("--rebuild")})`)}`),
|
package/cli/src/dev.mjs
CHANGED
|
@@ -6,6 +6,7 @@ import { connect as netConnect } from "node:net";
|
|
|
6
6
|
import { resolve } from "node:path";
|
|
7
7
|
import { fileURLToPath } from "node:url";
|
|
8
8
|
import { runDevUi } from "./devUi.mjs";
|
|
9
|
+
import { prebuildBackend } from "./devBack.mjs";
|
|
9
10
|
import { claimDevSession, stopDevBackContainers } from "./devSession.mjs";
|
|
10
11
|
import { ensureLocalMuscat, GATEWAY_PORT, isPortInUse, MUSCAT_CONTAINER, robotHasMuscat } from "./muscatLocal.mjs";
|
|
11
12
|
import { resolveSim, startSim, stopSims } from "./sim.mjs";
|
|
@@ -126,6 +127,7 @@ export async function runDev(args = []) {
|
|
|
126
127
|
const remoteRobot = isRemoteRobot(robotIp);
|
|
127
128
|
// Before dev:back is spawned: it inherits the id through the environment.
|
|
128
129
|
devPluginId(readManifest(root).id, { robotIp, args });
|
|
130
|
+
await prebuildBackend(root);
|
|
129
131
|
const hostAgent = await maybeStartHostAgent(root, { robotIp, robotToken });
|
|
130
132
|
const proxyEndpoint = process.env.MUSCAT_PROXY_ENDPOINT || "";
|
|
131
133
|
// No proxy (Linux, disabled, ...): fall back to the container reverse-dialing
|
package/cli/src/devBack.mjs
CHANGED
|
@@ -30,12 +30,14 @@ import {
|
|
|
30
30
|
import {
|
|
31
31
|
ROS2_DEV_IMAGE,
|
|
32
32
|
assertDockerReady,
|
|
33
|
+
colconBuild,
|
|
33
34
|
ensureImage,
|
|
34
35
|
ros2PackageName,
|
|
35
36
|
} from "./ros2.mjs";
|
|
36
37
|
import {
|
|
37
38
|
CPP_DEV_IMAGE,
|
|
38
39
|
assertDockerReady as cppAssertDockerReady,
|
|
40
|
+
cmakeBuild,
|
|
39
41
|
ensureImage as cppEnsureImage,
|
|
40
42
|
} from "./cpp.mjs";
|
|
41
43
|
|
|
@@ -683,6 +685,28 @@ async function runCpp(root, portRanges, robotGateway) {
|
|
|
683
685
|
process.on("SIGHUP", cleanup);
|
|
684
686
|
}
|
|
685
687
|
|
|
688
|
+
// `dev` builds the image and the backend first so the runtime and UI come up with it ready;
|
|
689
|
+
// dev:back's own build is then incremental. A failed build is left to dev:back's watcher.
|
|
690
|
+
export async function prebuildBackend(root) {
|
|
691
|
+
try {
|
|
692
|
+
const type = manifestRuntime(root);
|
|
693
|
+
if (type === "cpp") {
|
|
694
|
+
cppAssertDockerReady();
|
|
695
|
+
await cppEnsureImage();
|
|
696
|
+
cmakeBuild(root);
|
|
697
|
+
} else if (type === "ros2") {
|
|
698
|
+
assertDockerReady();
|
|
699
|
+
await ensureImage();
|
|
700
|
+
colconBuild(root, { symlink: true });
|
|
701
|
+
} else {
|
|
702
|
+
pyAssertDockerReady();
|
|
703
|
+
await pyEnsureImage();
|
|
704
|
+
}
|
|
705
|
+
} catch (e) {
|
|
706
|
+
log.warn(`backend build: ${e.message}`);
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
|
|
686
710
|
function warnManifest(root) {
|
|
687
711
|
const manifest = readManifest(root);
|
|
688
712
|
if (!manifest || Object.keys(manifest).length === 0) return;
|
package/cli/src/sim.mjs
CHANGED
|
@@ -14,7 +14,6 @@ const SIM_LABEL = "com.rainbow-robotics.muscat-pk.sim";
|
|
|
14
14
|
// ponytail: model table in code; move to S3 version.json when sims are versioned with Muscat (amr: no sim yet)
|
|
15
15
|
// sim name → coreSW RB_MODEL per component, and the Muscat robot model it registers as.
|
|
16
16
|
const COBOT_MODELS = {
|
|
17
|
-
"500880": { robotModel: "C500880", models: ["500880"] },
|
|
18
17
|
"500920": { robotModel: "C500920", models: ["500920"] },
|
|
19
18
|
RBY2: { robotModel: "RBY2", models: ["C500880", "C501880", "C502880"] },
|
|
20
19
|
};
|
|
@@ -38,7 +37,7 @@ export function runSimList() {
|
|
|
38
37
|
for (const t of RBY1_TYPES) console.log(`rby1-${t}\tRB-Y1 ${t.toUpperCase()}`);
|
|
39
38
|
}
|
|
40
39
|
|
|
41
|
-
/** "
|
|
40
|
+
/** "500920" | "RBY2" | "rby1-m" | "rby1-m_v1.2" → { services, env, ... } or null. */
|
|
42
41
|
export function parseSim(name) {
|
|
43
42
|
if (COBOT_MODELS[name]) return { name, kind: "cobot", services: ["log", "manipulate"], env: {}, ...COBOT_MODELS[name] };
|
|
44
43
|
const m = /^rby1-(a|m|ub)(?:_(v[\d.]+))?$/.exec(name ?? "");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"generatedAt":
|
|
1
|
+
{"generatedAt":1793172604703,"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.10.
|
|
3
|
+
"version": "1.10.4-dev.0",
|
|
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.10.
|
|
57
|
-
"@rainbow-robotics/preview-host": "1.10.
|
|
56
|
+
"@rainbow-robotics/plugin-ui": "1.10.4-dev.0",
|
|
57
|
+
"@rainbow-robotics/preview-host": "1.10.4-dev.0",
|
|
58
58
|
"@types/react": "^19.0.10",
|
|
59
59
|
"postcss": "^8.5.8",
|
|
60
60
|
"typescript": "^5.8.0",
|