diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9375499..4ae197d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -78,8 +78,8 @@ jobs: chmod +x rojo sudo mv rojo /usr/local/bin/rojo rojo --version - - run: mkdir -p dist && rojo build plugin/default.project.json -o dist/Brickbot.rbxmx + - run: mkdir -p dist && rojo build plugin/default.project.json -o dist/Roickbot.rbxmx - uses: actions/upload-artifact@v4 with: - name: Brickbot-plugin - path: dist/Brickbot.rbxmx + name: Roickbot-plugin + path: dist/Roickbot.rbxmx diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8eac4dc..631a7cc 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -28,11 +28,11 @@ jobs: chmod +x rojo sudo mv rojo /usr/local/bin/rojo rojo --version - - run: mkdir -p dist && rojo build plugin/default.project.json -o dist/Brickbot.rbxmx + - run: mkdir -p dist && rojo build plugin/default.project.json -o dist/Roickbot.rbxmx - uses: actions/upload-artifact@v4 with: - name: Brickbot-plugin - path: dist/Brickbot.rbxmx + name: Roickbot-plugin + path: dist/Roickbot.rbxmx desktop: name: Build desktop app (${{ matrix.os }}) @@ -51,7 +51,7 @@ jobs: # 插件 .rbxmx 需放到 dist/ 供 electron-builder 的 extraResources 打包。 - uses: actions/download-artifact@v4 with: - name: Brickbot-plugin + name: Roickbot-plugin path: dist - run: npm ci - run: npm run build:core diff --git a/.gitignore b/.gitignore index 649a834..f343ce6 100644 --- a/.gitignore +++ b/.gitignore @@ -16,4 +16,4 @@ bench-results.json bench-summary.md # Packaged plugin artifact (built from plugin/src) -Brickbot.rbxmx +Roickbot.rbxmx diff --git a/.mcp.json.example b/.mcp.json.example index 18e322d..e04660a 100644 --- a/.mcp.json.example +++ b/.mcp.json.example @@ -1,6 +1,6 @@ { "mcpServers": { - "brickbot": { + "roickbot": { "type": "http", "url": "http://127.0.0.1:7331/mcp", "headers": { diff --git a/README.md b/README.md index e087c9d..993d242 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ -# Brickbot - -[![CI](https://github.com/TonyD365/Brickbot/actions/workflows/ci.yml/badge.svg)](https://github.com/TonyD365/Brickbot/actions/workflows/ci.yml) -[![Latest release](https://img.shields.io/github/v/release/TonyD365/Brickbot?sort=semver)](https://github.com/TonyD365/Brickbot/releases/latest) -[![Downloads total](https://img.shields.io/github/downloads/TonyD365/Brickbot/total?label=downloads)](https://github.com/TonyD365/Brickbot/releases) -[![Downloads latest](https://img.shields.io/github/downloads/TonyD365/Brickbot/latest/total?label=downloads%40latest)](https://github.com/TonyD365/Brickbot/releases/latest) -[![Stars](https://img.shields.io/github/stars/TonyD365/Brickbot?style=flat)](https://github.com/TonyD365/Brickbot/stargazers) -[![Last commit](https://img.shields.io/github/last-commit/TonyD365/Brickbot)](https://github.com/TonyD365/Brickbot/commits) +# Roickbot + +[![CI](https://github.com/TonyD365/Roickbot/actions/workflows/ci.yml/badge.svg)](https://github.com/TonyD365/Roickbot/actions/workflows/ci.yml) +[![Latest release](https://img.shields.io/github/v/release/TonyD365/Roickbot?sort=semver)](https://github.com/TonyD365/Roickbot/releases/latest) +[![Downloads total](https://img.shields.io/github/downloads/TonyD365/Roickbot/total?label=downloads)](https://github.com/TonyD365/Roickbot/releases) +[![Downloads latest](https://img.shields.io/github/downloads/TonyD365/Roickbot/latest/total?label=downloads%40latest)](https://github.com/TonyD365/Roickbot/releases/latest) +[![Stars](https://img.shields.io/github/stars/TonyD365/Roickbot?style=flat)](https://github.com/TonyD365/Roickbot/stargazers) +[![Last commit](https://img.shields.io/github/last-commit/TonyD365/Roickbot)](https://github.com/TonyD365/Roickbot/commits) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) A desktop app + MCP server that lets **Claude Code — and any other MCP client (Gemini, Cursor, @@ -18,7 +18,7 @@ all through natural language from your editor. > working, secured bridge with tools for scripts, instances, properties, selection, run/test, > and building scenes (parts, terrain, lighting, decals, models, GUI), plus a universal > `run_luau` escape hatch. Phase 3 (Bot vision) is next. Cross-platform installers with -> auto-update are published on the [Releases](https://github.com/TonyD365/Brickbot/releases) page. +> auto-update are published on the [Releases](https://github.com/TonyD365/Roickbot/releases) page. *(中文版见下方 / Chinese version below.)* @@ -97,16 +97,16 @@ See [docs/PROTOCOL.md](docs/PROTOCOL.md) for the full wire protocol. ## Installation (end user) 1. **Install the desktop app** from the - [Releases](https://github.com/TonyD365/Brickbot/releases) page — a macOS `.dmg` + [Releases](https://github.com/TonyD365/Roickbot/releases) page — a macOS `.dmg` (Universal: Intel + Apple Silicon) or a Windows `.exe` (x64, runs on Intel and ARM). 2. **Start the service** in the app, pick your client from the dropdown (Claude Code, Cursor, - Gemini CLI, Cline, VS Code) and click **Install MCP config** — the app writes the `brickbot` + Gemini CLI, Cline, VS Code) and click **Install MCP config** — the app writes the `roickbot` server in that client's exact format and location for you. Then restart the client. 3. **Install the plugin**: if it shows offline, click **Install plugin** and save - `Brickbot.rbxmx` into your Studio Plugins folder. + `Roickbot.rbxmx` into your Studio Plugins folder. 4. **Enable HTTP** in Studio's Command Bar (once per place): `game:GetService("HttpService").HttpEnabled = true` -5. **Pair**: copy the token from the app, paste it into the Brickbot plugin panel in Studio, +5. **Pair**: copy the token from the app, paste it into the Roickbot plugin panel in Studio, and click **Connect**. 6. **Verify**: ask Claude to call the `health` tool — it should report `pluginConnected: true`. @@ -125,7 +125,7 @@ To run the desktop app from source you also need the Electron binary (run `npm i `ELECTRON_SKIP_BINARY_DOWNLOAD`) and a built plugin: ```bash -npm run build:plugin # requires Rojo (see plugin/aftman.toml) -> dist/Brickbot.rbxmx +npm run build:plugin # requires Rojo (see plugin/aftman.toml) -> dist/Roickbot.rbxmx npm run build:desktop npm start --workspace packages/desktop ``` @@ -184,7 +184,7 @@ client automatically (each one differs slightly, e.g. Cline needs `streamableHtt ```json { "mcpServers": { - "brickbot": { + "roickbot": { "httpUrl": "http://127.0.0.1:7331/mcp", "headers": { "Authorization": "Bearer PASTE_TOKEN", "X-Roblox-MCP": "1" } } @@ -236,14 +236,14 @@ MIT
-# Brickbot(中文) +# Roickbot(中文) -[![CI](https://github.com/TonyD365/Brickbot/actions/workflows/ci.yml/badge.svg)](https://github.com/TonyD365/Brickbot/actions/workflows/ci.yml) -[![Latest release](https://img.shields.io/github/v/release/TonyD365/Brickbot?sort=semver)](https://github.com/TonyD365/Brickbot/releases/latest) -[![Downloads total](https://img.shields.io/github/downloads/TonyD365/Brickbot/total?label=downloads)](https://github.com/TonyD365/Brickbot/releases) -[![Downloads latest](https://img.shields.io/github/downloads/TonyD365/Brickbot/latest/total?label=downloads%40latest)](https://github.com/TonyD365/Brickbot/releases/latest) -[![Stars](https://img.shields.io/github/stars/TonyD365/Brickbot?style=flat)](https://github.com/TonyD365/Brickbot/stargazers) -[![Last commit](https://img.shields.io/github/last-commit/TonyD365/Brickbot)](https://github.com/TonyD365/Brickbot/commits) +[![CI](https://github.com/TonyD365/Roickbot/actions/workflows/ci.yml/badge.svg)](https://github.com/TonyD365/Roickbot/actions/workflows/ci.yml) +[![Latest release](https://img.shields.io/github/v/release/TonyD365/Roickbot?sort=semver)](https://github.com/TonyD365/Roickbot/releases/latest) +[![Downloads total](https://img.shields.io/github/downloads/TonyD365/Roickbot/total?label=downloads)](https://github.com/TonyD365/Roickbot/releases) +[![Downloads latest](https://img.shields.io/github/downloads/TonyD365/Roickbot/latest/total?label=downloads%40latest)](https://github.com/TonyD365/Roickbot/releases/latest) +[![Stars](https://img.shields.io/github/stars/TonyD365/Roickbot?style=flat)](https://github.com/TonyD365/Roickbot/stargazers) +[![Last commit](https://img.shields.io/github/last-commit/TonyD365/Roickbot)](https://github.com/TonyD365/Roickbot/commits) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) 一个桌面应用 + MCP 服务器,让 **Claude Code —— 以及任何其它 MCP 客户端(Gemini、Cursor、VS Code…)** @@ -254,7 +254,7 @@ MIT > **状态:** v1.0.0 已发布。第一阶段(核心)与第二阶段(做图)均已完成 —— 一条可用且带安全鉴权的桥, > 涵盖脚本、实例、属性、选择、运行/测试,以及搭建场景(Part、地形、光照、贴图、模型、GUI),外加万能的 > `run_luau` 逃生舱。第三阶段(Bot 视觉)进行中。带自动更新的跨平台安装包见 -> [Releases](https://github.com/TonyD365/Brickbot/releases) 页面。 +> [Releases](https://github.com/TonyD365/Roickbot/releases) 页面。 ## 目录 @@ -318,15 +318,15 @@ Studio 插件通过 **WebSocket**(Studio 的 `HttpService:CreateWebStreamClien ## 安装(最终用户) -1. 从 [Releases](https://github.com/TonyD365/Brickbot/releases) 页面**下载桌面应用** +1. 从 [Releases](https://github.com/TonyD365/Roickbot/releases) 页面**下载桌面应用** (Windows `.exe` 或 macOS `.dmg`,arm64 / x64)。 2. 在应用里**启动服务**,从下拉框选择你的客户端(Claude Code、Cursor、Gemini CLI、Cline、VS Code) - 再点 **Install MCP config** —— 应用会按该客户端正确的格式与路径自动写入 `brickbot` 服务, + 再点 **Install MCP config** —— 应用会按该客户端正确的格式与路径自动写入 `roickbot` 服务, 然后重启对应客户端。 -3. **安装插件**:若显示离线,点 **Install plugin**,把 `Brickbot.rbxmx` 保存到 Studio 的 Plugins 目录。 +3. **安装插件**:若显示离线,点 **Install plugin**,把 `Roickbot.rbxmx` 保存到 Studio 的 Plugins 目录。 4. 在 Studio 命令栏**启用 HTTP**(每个 place 一次): `game:GetService("HttpService").HttpEnabled = true` -5. **配对**:从应用复制 token,粘贴进 Studio 里的 Brickbot 插件面板,点 **Connect**。 +5. **配对**:从应用复制 token,粘贴进 Studio 里的 Roickbot 插件面板,点 **Connect**。 6. **验证**:让 Claude 调用 `health` 工具 —— 应返回 `pluginConnected: true`。 完整步骤见 [docs/INSTALL.md](docs/INSTALL.md)。 @@ -344,7 +344,7 @@ node smoke.mjs # 端到端桥烟雾测试(无需 Studio) `ELECTRON_SKIP_BINARY_DOWNLOAD`)以及构建好的插件: ```bash -npm run build:plugin # 需要 Rojo(见 plugin/aftman.toml) -> dist/Brickbot.rbxmx +npm run build:plugin # 需要 Rojo(见 plugin/aftman.toml) -> dist/Roickbot.rbxmx npm run build:desktop npm start --workspace packages/desktop ``` @@ -396,7 +396,7 @@ npm start --workspace packages/desktop ```json { "mcpServers": { - "brickbot": { + "roickbot": { "httpUrl": "http://127.0.0.1:7331/mcp", "headers": { "Authorization": "Bearer 粘贴你的token", "X-Roblox-MCP": "1" } } diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index afdcb2b..e9fef30 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,4 +1,4 @@ -## Brickbot v0.1.0 — Phase 1: the core bridge +## Roickbot v0.1.0 — Phase 1: the core bridge The first release. This is a working, secured bridge that lets **Claude / Claude Code** control a Roblox Studio session in natural language — read and edit scripts, inspect and modify the scene, @@ -27,14 +27,14 @@ run the simulation, and run arbitrary Luau. | --- | --- | | `Claude.for.Roblox.Studio-*-arm64.dmg` / `-x64.dmg` | macOS desktop app (Apple Silicon / Intel) | | `Claude.for.Roblox.Studio-*-x64.exe` / `-arm64.exe` | Windows desktop app | -| `Brickbot.rbxmx` | The Roblox Studio plugin (drop into your Studio Plugins folder) | +| `Roickbot.rbxmx` | The Roblox Studio plugin (drop into your Studio Plugins folder) | | `SHA256SUMS` | Checksums for the files above | ### Getting started 1. Install the desktop app, click **Start service**, then **Install MCP config**, and restart Claude Code. -2. Install `Brickbot.rbxmx` into Studio, enable HTTP +2. Install `Roickbot.rbxmx` into Studio, enable HTTP (`game:GetService("HttpService").HttpEnabled = true`), paste the token into the plugin, and click **Connect**. 3. Ask Claude to call the `health` tool — it should report `pluginConnected: true`. @@ -54,5 +54,5 @@ Full guide: [docs/INSTALL.md](docs/INSTALL.md) · Tools: [docs/TOOLS.md](docs/TO 首个版本,第一阶段核心:让 Claude / Claude Code 用自然语言操控 Roblox Studio —— 读写脚本、查看与修改 场景、运行仿真、执行任意 Luau。安全方面只绑回环、随机 token、`Host`/`Origin` 校验、必需自定义头,防御 恶意网页;破坏性操作先 dry-run 预览 + 确认,所有更改可撤销。下载桌面应用(Win/macOS,arm64+x64)和插件 -`Brickbot.rbxmx`,按 [docs/INSTALL.md](docs/INSTALL.md) 配置即可。安装包暂未签名,首次打开需绕过 +`Roickbot.rbxmx`,按 [docs/INSTALL.md](docs/INSTALL.md) 配置即可。安装包暂未签名,首次打开需绕过 Gatekeeper / SmartScreen。 diff --git a/docs/CLIENTS.md b/docs/CLIENTS.md index c2829cb..64a067f 100644 --- a/docs/CLIENTS.md +++ b/docs/CLIENTS.md @@ -42,7 +42,7 @@ The **Gemini CLI** is free, has a generous free tier, and is good at tool use. ```json { "mcpServers": { - "brickbot": { + "roickbot": { "httpUrl": "http://127.0.0.1:7331/mcp", "headers": { "Authorization": "Bearer PASTE_TOKEN_FROM_THE_APP", @@ -63,7 +63,7 @@ Add to `~/.cursor/mcp.json` (global) or `.cursor/mcp.json` (project): ```json { "mcpServers": { - "brickbot": { + "roickbot": { "url": "http://127.0.0.1:7331/mcp", "headers": { "Authorization": "Bearer PASTE_TOKEN", "X-Roblox-MCP": "1" } } @@ -78,7 +78,7 @@ Add to `.vscode/mcp.json`: ```json { "servers": { - "brickbot": { + "roickbot": { "type": "http", "url": "http://127.0.0.1:7331/mcp", "headers": { "Authorization": "Bearer PASTE_TOKEN", "X-Roblox-MCP": "1" } @@ -95,7 +95,7 @@ Use the app's **Install MCP config** button, or add it manually (see ```json { "mcpServers": { - "brickbot": { + "roickbot": { "type": "http", "url": "http://127.0.0.1:7331/mcp", "headers": { "Authorization": "Bearer PASTE_TOKEN", "X-Roblox-MCP": "1" } @@ -115,7 +115,7 @@ won't connect. Add this to its `cline_mcp_settings.json`: ```json { "mcpServers": { - "brickbot": { + "roickbot": { "type": "streamableHttp", "url": "http://127.0.0.1:7331/mcp", "headers": { "Authorization": "Bearer PASTE_TOKEN", "X-Roblox-MCP": "1" }, diff --git a/docs/INSTALL.md b/docs/INSTALL.md index a88d63b..3b7e9aa 100644 --- a/docs/INSTALL.md +++ b/docs/INSTALL.md @@ -3,7 +3,7 @@ ## 1. Install the desktop app Download the installer for your platform from the -[Releases](https://github.com/tonyd365/brickbot/releases) page: +[Releases](https://github.com/tonyd365/roickbot/releases) page: - **Windows**: `.exe` (x64 / arm64) - **macOS**: `.dmg` (Apple Silicon arm64 / Intel x64) @@ -14,7 +14,7 @@ right-click → Open) or SmartScreen (Windows: More info → Run anyway). ## 2. Start the service and connect Claude Code 1. Open the app and click **Start service**. -2. Click **Install MCP config** — this writes the `brickbot` server into your Claude Code +2. Click **Install MCP config** — this writes the `roickbot` server into your Claude Code config (`~/.claude.json`) pointing at `http://127.0.0.1:7331/mcp` with your token. 3. Restart Claude Code so it picks up the new MCP server. @@ -23,7 +23,7 @@ You can also configure it manually; see [`.mcp.json.example`](../.mcp.json.examp ## 3. Install the Studio plugin 1. In the app, if the plugin is offline, click **Install plugin** and choose where to save - `Brickbot.rbxmx`. The simplest location is your Studio **Plugins** folder: + `Roickbot.rbxmx`. The simplest location is your Studio **Plugins** folder: - Windows: `%LOCALAPPDATA%\Roblox\Plugins` - macOS: `~/Documents/Roblox/Plugins` (Or in Studio, right-click the model and choose *Save as Local Plugin*.) @@ -35,7 +35,7 @@ You can also configure it manually; see [`.mcp.json.example`](../.mcp.json.examp ```lua game:GetService("HttpService").HttpEnabled = true ``` -2. Open the **Brickbot** plugin panel (toolbar button). +2. Open the **Roickbot** plugin panel (toolbar button). 3. Copy the **token** from the desktop app, paste it into the plugin, and click **Connect**. The plugin remembers the token and auto-connects next time. diff --git a/package-lock.json b/package-lock.json index 119dfd2..fe0f186 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { - "name": "brickbot", + "name": "roickbot", "version": "0.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "brickbot", + "name": "roickbot", "version": "0.1.0", "license": "MIT", "workspaces": [ @@ -16,14 +16,6 @@ "node": ">=20" } }, - "node_modules/@brickbot/core": { - "resolved": "packages/core", - "link": true - }, - "node_modules/@brickbot/desktop": { - "resolved": "packages/desktop", - "link": true - }, "node_modules/@develar/schema-utils": { "version": "2.6.5", "resolved": "https://registry.npmjs.org/@develar/schema-utils/-/schema-utils-2.6.5.tgz", @@ -991,6 +983,14 @@ "node": ">=14" } }, + "node_modules/@roickbot/core": { + "resolved": "packages/core", + "link": true + }, + "node_modules/@roickbot/desktop": { + "resolved": "packages/desktop", + "link": true + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.61.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.61.1.tgz", @@ -6514,7 +6514,7 @@ } }, "packages/core": { - "name": "@brickbot/core", + "name": "@roickbot/core", "version": "0.1.0", "license": "MIT", "dependencies": { @@ -6523,7 +6523,7 @@ "zod": "^3.23.8" }, "bin": { - "claude-roblox-server": "dist/cli.js" + "roickbot-server": "dist/cli.js" }, "devDependencies": { "@types/node": "^22.0.0", @@ -6533,11 +6533,11 @@ } }, "packages/desktop": { - "name": "@brickbot/desktop", + "name": "@roickbot/desktop", "version": "0.1.0", "license": "MIT", "dependencies": { - "@brickbot/core": "0.1.0", + "@roickbot/core": "0.1.0", "electron-updater": "^6.3.9" }, "devDependencies": { diff --git a/package.json b/package.json index 44e63ef..69a7e17 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "brickbot", + "name": "roickbot", "version": "0.1.0", "private": true, "description": "Desktop app + MCP server that lets Claude / Claude Code control Roblox Studio.", @@ -14,7 +14,7 @@ "build:desktop": "npm run build --workspace packages/desktop", "typecheck": "npm run typecheck --workspace packages/core && npm run typecheck --workspace packages/desktop", "test": "npm run test --workspace packages/core", - "build:plugin": "rojo build plugin/default.project.json -o dist/Brickbot.rbxmx", + "build:plugin": "rojo build plugin/default.project.json -o dist/Roickbot.rbxmx", "dev:core": "npm run dev --workspace packages/core" }, "engines": { diff --git a/packages/core/package.json b/packages/core/package.json index 4c1862e..7a36c6e 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,7 +1,7 @@ { - "name": "@brickbot/core", + "name": "@roickbot/core", "version": "0.1.0", - "description": "Core MCP server + Studio bridge + security for Brickbot.", + "description": "Core MCP server + Studio bridge + security for Roickbot.", "license": "MIT", "type": "module", "main": "dist/index.js", @@ -17,7 +17,7 @@ "start": "node dist/cli.js" }, "bin": { - "brickbot-server": "dist/cli.js" + "roickbot-server": "dist/cli.js" }, "dependencies": { "@modelcontextprotocol/sdk": "^1.12.0", diff --git a/packages/core/src/cli.ts b/packages/core/src/cli.ts index e8f4ea2..03921f4 100644 --- a/packages/core/src/cli.ts +++ b/packages/core/src/cli.ts @@ -16,14 +16,14 @@ async function main(): Promise { await service.start(); - console.log("Brickbot bridge is running."); + console.log("Roickbot bridge is running."); console.log(` MCP endpoint : http://127.0.0.1:${service.port}/mcp`); console.log(` Token : ${service.getToken()}`); console.log(""); console.log("Add this to your Claude Code .mcp.json:"); - console.log(JSON.stringify({ mcpServers: { "brickbot": buildMcpEntry(service.port, service.getToken()) } }, null, 2)); + console.log(JSON.stringify({ mcpServers: { "roickbot": buildMcpEntry(service.port, service.getToken()) } }, null, 2)); console.log(""); - console.log("Then paste the token into the Brickbot plugin in Roblox Studio and click Connect."); + console.log("Then paste the token into the Roickbot plugin in Roblox Studio and click Connect."); const shutdown = async () => { console.log("\nShutting down..."); diff --git a/packages/core/src/config/mcpConfig.ts b/packages/core/src/config/mcpConfig.ts index 515d16c..3da6e32 100644 --- a/packages/core/src/config/mcpConfig.ts +++ b/packages/core/src/config/mcpConfig.ts @@ -6,7 +6,7 @@ import { promises as fs } from "node:fs"; import { homedir } from "node:os"; import { dirname, join } from "node:path"; -export const MCP_SERVER_KEY = "brickbot"; +export const MCP_SERVER_KEY = "roickbot"; /** 受支持的 MCP 客户端。 */ export type McpClient = "claude" | "cursor" | "gemini" | "cline" | "vscode"; diff --git a/packages/core/src/mcp/server.ts b/packages/core/src/mcp/server.ts index 86680c7..01eb759 100644 --- a/packages/core/src/mcp/server.ts +++ b/packages/core/src/mcp/server.ts @@ -9,7 +9,7 @@ import { registerHarnessTools } from "./registerHarness.js"; import { registerRuntimeTools } from "./registerRuntimeTools.js"; import type { ToolContext } from "../tools/types.js"; -export const SERVER_NAME = "brickbot"; +export const SERVER_NAME = "roickbot"; export const SERVER_VERSION = "0.2.0"; /** 创建并返回一个新的 McpServer(Phase 1 + Phase 2 工具已注册)。 */ diff --git a/packages/core/src/tools/types.ts b/packages/core/src/tools/types.ts index 3160336..fc81a6d 100644 --- a/packages/core/src/tools/types.ts +++ b/packages/core/src/tools/types.ts @@ -60,7 +60,7 @@ export async function forward( const text = useAgent ? "The server runtime agent is not connected. Call start_test first — it injects an agent into the " + "running game so server-context tools can run. (The agent only exists while a test is running.)" - : "The Roblox Studio plugin is not connected. Open Studio, install/enable the Brickbot plugin, " + + : "The Roblox Studio plugin is not connected. Open Studio, install/enable the Roickbot plugin, " + "and connect it using the token shown in the desktop app."; return { content: [{ type: "text", text }], isError: true }; } diff --git a/packages/desktop/electron-builder.yml b/packages/desktop/electron-builder.yml index 5c5e6ce..8be5fce 100644 --- a/packages/desktop/electron-builder.yml +++ b/packages/desktop/electron-builder.yml @@ -1,10 +1,10 @@ -appId: com.brickbot.app -productName: Brickbot -copyright: Brickbot +appId: com.roickbot.app +productName: Roickbot +copyright: Roickbot # 输出文件名不能带空格:productName 有空格会导致生成名与 GitHub 上传后(空格→点)的 # 资源名不一致,使 electron-updater 下载更新时 404。用无空格的 artifactName 统一三者。 -artifactName: Brickbot-${version}-${arch}.${ext} +artifactName: Roickbot-${version}-${arch}.${ext} # 在 npm workspaces(monorepo)下 electron-builder 无法从被提升的 node_modules # 自动推断 electron 版本,故显式指定,避免 "Cannot compute electron version"。 @@ -15,7 +15,7 @@ electronVersion: 31.7.7 publish: provider: github owner: TonyD365 - repo: Brickbot + repo: Roickbot directories: output: release @@ -29,10 +29,10 @@ files: # 把预编译的 Studio 插件随包带上,供 UI 的 "Install plugin" 使用。 extraResources: - - from: ../../dist/Brickbot.rbxmx - to: Brickbot.rbxmx + - from: ../../dist/Roickbot.rbxmx + to: Roickbot.rbxmx -# 让 electron-builder 把 workspace 依赖 @brickbot/core 一并打入。 +# 让 electron-builder 把 workspace 依赖 @roickbot/core 一并打入。 includeSubNodeModules: true npmRebuild: false diff --git a/packages/desktop/package.json b/packages/desktop/package.json index 185f11e..eaa6924 100644 --- a/packages/desktop/package.json +++ b/packages/desktop/package.json @@ -1,12 +1,12 @@ { - "name": "@brickbot/desktop", + "name": "@roickbot/desktop", "version": "0.1.0", - "description": "Desktop app (Electron) for Brickbot.", + "description": "Desktop app (Electron) for Roickbot.", "license": "MIT", "author": "TonyD365", "repository": { "type": "git", - "url": "https://github.com/TonyD365/Brickbot.git" + "url": "https://github.com/TonyD365/Roickbot.git" }, "main": "dist/main/index.js", "scripts": { @@ -17,7 +17,7 @@ "dist": "npm run build && electron-builder --config electron-builder.yml --publish never" }, "dependencies": { - "@brickbot/core": "0.1.0", + "@roickbot/core": "0.1.0", "electron-updater": "^6.3.9" }, "devDependencies": { diff --git a/packages/desktop/scripts/screenshot.mjs b/packages/desktop/scripts/screenshot.mjs index ee39c6a..7f1974e 100644 --- a/packages/desktop/scripts/screenshot.mjs +++ b/packages/desktop/scripts/screenshot.mjs @@ -13,7 +13,7 @@ const out = resolve(process.argv[2] || join(appDir, "ui-screenshot.png")); const child = spawn("xvfb-run", ["-a", electronPath, appDir, "--no-sandbox", "--disable-gpu"], { cwd: appDir, - env: { ...process.env, BRICKBOT_DEBUG: "0", BRICKBOT_SCREENSHOT: out }, + env: { ...process.env, ROICKBOT_DEBUG: "0", ROICKBOT_SCREENSHOT: out }, detached: true, }); diff --git a/packages/desktop/scripts/smoke-app.mjs b/packages/desktop/scripts/smoke-app.mjs index 774eb33..928415f 100644 --- a/packages/desktop/scripts/smoke-app.mjs +++ b/packages/desktop/scripts/smoke-app.mjs @@ -34,7 +34,7 @@ console.log(`Launching app headlessly: ${electronPath} ${appDir}`); // --no-sandbox / --disable-gpu:便于在 CI / root 容器的无头环境里启动。 const child = spawn("xvfb-run", ["-a", electronPath, appDir, "--no-sandbox", "--disable-gpu"], { cwd: appDir, - env: { ...process.env, BRICKBOT_DEBUG: "0" }, + env: { ...process.env, ROICKBOT_DEBUG: "0" }, detached: true, }); diff --git a/packages/desktop/src/main/index.ts b/packages/desktop/src/main/index.ts index 7701827..3020d4c 100644 --- a/packages/desktop/src/main/index.ts +++ b/packages/desktop/src/main/index.ts @@ -9,7 +9,7 @@ import { createWriteStream } from "node:fs"; // electron-updater 是 CommonJS 具名导出,必须具名导入(它没有 default 导出)。 import { autoUpdater } from "electron-updater"; -const REPO = "TonyD365/Brickbot"; +const REPO = "TonyD365/Roickbot"; const isMac = process.platform === "darwin"; // core 是 ESM-only 包,从 CommonJS 主进程通过动态 import 加载,故这里用宽松类型。 @@ -41,8 +41,8 @@ let core: any; // eslint-disable-next-line @typescript-eslint/no-explicit-any let service: any; -/** 调试开关:打包后默认关闭 DevTools;设 BRICKBOT_DEBUG=1 可强制打开。 */ -const DEBUG = process.env.BRICKBOT_DEBUG === "1" || !app.isPackaged; +/** 调试开关:打包后默认关闭 DevTools;设 ROICKBOT_DEBUG=1 可强制打开。 */ +const DEBUG = process.env.ROICKBOT_DEBUG === "1" || !app.isPackaged; // 兜底:electron-updater 内部下载失败等会抛出未捕获的 Promise 拒绝,记录而非让它变成警告噪音。 process.on("unhandledRejection", (reason) => { @@ -51,8 +51,8 @@ process.on("unhandledRejection", (reason) => { /** 预编译插件 .rbxmx 的位置(打包后在 resources/,开发时在仓库 dist/)。 */ function pluginArtifactPath(): string { - if (app.isPackaged) return join(process.resourcesPath, "Brickbot.rbxmx"); - return join(app.getAppPath(), "..", "..", "dist", "Brickbot.rbxmx"); + if (app.isPackaged) return join(process.resourcesPath, "Roickbot.rbxmx"); + return join(app.getAppPath(), "..", "..", "dist", "Roickbot.rbxmx"); } function createWindow(): void { @@ -63,7 +63,7 @@ function createWindow(): void { width: 540, height: 700, // 版本号放进标题栏:即使渲染层出问题,也能一眼看出是不是新版本实例。 - title: `Brickbot v${app.getVersion()}`, + title: `Roickbot v${app.getVersion()}`, webPreferences: { preload: preloadPath, contextIsolation: true, @@ -96,15 +96,15 @@ function createWindow(): void { win = null; }); - // 开发用:BRICKBOT_SCREENSHOT= 时,加载后截图保存(供 UI 迭代验证)。 - if (process.env.BRICKBOT_SCREENSHOT) { + // 开发用:ROICKBOT_SCREENSHOT= 时,加载后截图保存(供 UI 迭代验证)。 + if (process.env.ROICKBOT_SCREENSHOT) { win.webContents.on("did-finish-load", () => { setTimeout(() => { void win!.webContents .capturePage() .then(async (img) => { const { writeFileSync } = await import("node:fs"); - writeFileSync(process.env.BRICKBOT_SCREENSHOT!, img.toPNG()); + writeFileSync(process.env.ROICKBOT_SCREENSHOT!, img.toPNG()); console.log("[main] screenshot saved"); }) .catch((e) => console.error("[main] screenshot failed:", e)); @@ -186,8 +186,8 @@ async function rotateToken(): Promise { /** 弹保存框把内置插件写到用户选择的位置。 */ async function installPlugin(): Promise<{ saved: boolean; path?: string }> { const result = await showSave({ - title: "Save Brickbot plugin", - defaultPath: "Brickbot.rbxmx", + title: "Save Roickbot plugin", + defaultPath: "Roickbot.rbxmx", filters: [{ name: "Roblox plugin", extensions: ["rbxmx"] }], }); if (result.canceled || !result.filePath) return { saved: false }; @@ -234,7 +234,7 @@ function menuAction(fn: () => unknown | Promise): () => void { return () => { Promise.resolve() .then(fn) - .catch((e) => dialog.showErrorBox("Brickbot", String((e as Error)?.message ?? e))); + .catch((e) => dialog.showErrorBox("Roickbot", String((e as Error)?.message ?? e))); }; } @@ -243,7 +243,7 @@ function menuTemplate(): MenuItemConstructorOptions[] { const running = service?.isRunning() ?? false; const hasToken = !!(service && service.getToken()); return [ - { label: "Open Brickbot", click: () => showWindow() }, + { label: "Open Roickbot", click: () => showWindow() }, { type: "separator" }, { label: running ? "Stop service" : "Start service", @@ -291,7 +291,7 @@ function createTray(): void { console.warn("[main] tray image missing; skipping tray"); } else { tray = new Tray(image); - tray.setToolTip(`Brickbot v${app.getVersion()}`); + tray.setToolTip(`Roickbot v${app.getVersion()}`); // 左键:打开/聚焦窗口(若已关则新建)。右键:弹出选项菜单(不打开窗口)。 tray.on("click", () => showWindow()); tray.on("right-click", () => { @@ -325,7 +325,7 @@ function registerIpc(): void { // macOS 半自动更新:把 dmg 下载到桌面并打开,用户自行拖进 Applications。 ipcMain.handle("download-update", async (_e, url: string) => { - const name = url.split("/").pop() || "Brickbot.dmg"; + const name = url.split("/").pop() || "Roickbot.dmg"; const dest = join(app.getPath("desktop"), name); await downloadFile(url, dest); await shell.openPath(dest); @@ -364,7 +364,7 @@ function downloadFile(url: string, dest: string): Promise { function fetchChangelog(version: string): Promise { return new Promise((resolve) => { const request = net.request(`https://api.github.com/repos/${REPO}/releases/tags/v${version}`); - request.setHeader("User-Agent", "Brickbot"); + request.setHeader("User-Agent", "Roickbot"); request.setHeader("Accept", "application/vnd.github+json"); let body = ""; request.on("response", (response) => { @@ -415,7 +415,7 @@ function startAutoUpdate(): void { console.log("[updater] update available:", info.version); if (isMac) { // mac 未签名:按需下载 Universal dmg,先弹更新日志(附下载按钮)。 - const file = `Brickbot-${info.version}-universal.dmg`; + const file = `Roickbot-${info.version}-universal.dmg`; const url = `https://github.com/${REPO}/releases/download/v${info.version}/${file}`; void announceUpdate(info.version, "mac", url); } @@ -444,8 +444,8 @@ if (!app.requestSingleInstanceLock()) { createWindow(); createTray(); - // 开发用:BRICKBOT_FAKE_UPDATE=1 时注入一个假的待安装更新,便于预览更新弹窗。 - if (process.env.BRICKBOT_FAKE_UPDATE) { + // 开发用:ROICKBOT_FAKE_UPDATE=1 时注入一个假的待安装更新,便于预览更新弹窗。 + if (process.env.ROICKBOT_FAKE_UPDATE) { pendingUpdate = { version: "9.9.9", kind: isMac ? "mac" : "win", @@ -459,12 +459,12 @@ if (!app.requestSingleInstanceLock()) { "### Fixes\n\n" + "- No more false disconnects during long commands\n" + "- Reliable handshake with retries\n\n" + - "See the [full release notes](https://github.com/TonyD365/Brickbot/releases) for details.", + "See the [full release notes](https://github.com/TonyD365/Roickbot/releases) for details.", }; } try { - core = await import("@brickbot/core"); + core = await import("@roickbot/core"); service = new core.CoreService({ tokenPath: join(app.getPath("userData"), "token") }); service.on("status", (s: CoreStatus) => { sendToRenderer("status", s); diff --git a/packages/desktop/src/renderer/index.html b/packages/desktop/src/renderer/index.html index 9cc93b3..856d106 100644 --- a/packages/desktop/src/renderer/index.html +++ b/packages/desktop/src/renderer/index.html @@ -2,7 +2,7 @@ - Brickbot + Roickbot