dominus-cli 2.0.0 → 2.1.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/CHANGELOG.md ADDED
@@ -0,0 +1,175 @@
1
+ # Changelog
2
+
3
+ ## 2.1.0 (2026-07-12)
4
+
5
+ Dominus has been rewritten as an MCP-first Roblox Studio engineering server.
6
+
7
+ ### MCP-native agent harness
8
+
9
+ - Removed the Ink/TUI command from the published binaries. Dominus now relies on
10
+ the MCP host's model, context, consent UI, and agent runtime.
11
+ - Replaced the monolithic legacy catalog with 17 focused tools for connection
12
+ management, inspection, transactional changes, UI, scripts, tests, and docs.
13
+ - Added strict input schemas, output schemas, `structuredContent`, text fallbacks,
14
+ `isError`, and accurate read-only/destructive/idempotent/open-world annotations.
15
+ - Added the `dominus-workflow` MCP prompt and `dominus://status` resource.
16
+ - Added explicit inspect, plan, apply, read-back, and test instructions, including
17
+ UI fidelity checks for fonts, UDim2 values, colors, strokes, and hierarchy.
18
+ - Updated the official MCP TypeScript SDK from 1.27.0 to 1.29.0.
19
+
20
+ ### Secure Studio bridge
21
+
22
+ - Bound the WebSocket bridge to `127.0.0.1` instead of every network interface.
23
+ - Added a persistent 256-bit bridge token and six-digit first-use pairing flow.
24
+ - Authenticated relay/controller processes as well as Studio plugin connections.
25
+ - Added one MiB payload limits, socket rate limits, handshake timeouts, bounded
26
+ request timeouts, and strict message-envelope validation.
27
+ - Removed arbitrary `run_code` from the MCP surface and removed the plugin's
28
+ `loadstring` executor from the packaged model.
29
+ - Isolated in-flight requests to the exact Studio WebSocket that owns them;
30
+ wrong-session responses are ignored and one disconnect cannot cancel another
31
+ session's work.
32
+
33
+ ### Multi-Studio correctness
34
+
35
+ - Replaced place-ID targeting with unique connection IDs. Multiple windows on the
36
+ same place ID are now safe and independently selectable.
37
+ - Relay clients carry their selected connection on each request, so separate MCP
38
+ processes cannot overwrite each other's active target.
39
+ - Added `dominus_status`, `dominus_pair_studio`, and `dominus_select_studio`.
40
+
41
+ ### Studio plugin harness
42
+
43
+ - Replaced the broken ten-port scanner with one configurable loopback endpoint and
44
+ exponential reconnect backoff.
45
+ - `WsClient` now waits for the real `WebStreamClient.Opened` event and handles
46
+ `Error`, `Closed`, timeouts, stale attempts, and signal cleanup correctly.
47
+ - Added a strict command allowlist and bounded command router.
48
+ - Added session-scoped instance references with path-segment fallback. Dots and
49
+ duplicate sibling names are no longer silently misresolved.
50
+ - Updated ReflectionService integration to current `Type`, `Display`, and `Permits`
51
+ fields.
52
+ - Added typed Roblox value encoding/decoding with surfaced property failures.
53
+ - Added atomic mutation batches backed by ChangeHistoryService recordings. Failed
54
+ batches cancel and automatically undo in-progress work.
55
+ - UI trees are fully built and validated off-tree before an existing UI is
56
+ replaced. Ambiguous replacements and silent property failures are rejected.
57
+ - Script reads return a revision hash; writes require it and reject stale edits.
58
+ - Studio tests now use bounded Run, Play, or Multiplayer StudioTestService flows,
59
+ reject overlapping runs, and leave timed-out sessions.
60
+ - Output forwarding excludes all Dominus-prefixed messages, closing the previous
61
+ WebSocket warning feedback loop.
62
+
63
+ ### Packaging and tests
64
+
65
+ - Added the `dominus-install-plugin` executable and fixed the previously missing
66
+ installer implementation.
67
+ - The published runtime dependency set is MCP-only; old CLI dependencies are
68
+ development-only and excluded from the MCP bundle.
69
+ - Added transport tests for auth, pairing, relays, duplicate places, wrong-target
70
+ responses, and disconnect isolation.
71
+ - Added in-memory MCP conformance tests for the tool catalog, structured outputs,
72
+ resources, prompts, routing, and error results.
73
+ - Added static plugin hardening tests and Rojo package verification.
74
+
75
+ ### Breaking changes
76
+
77
+ - The `dominus` TUI command is removed. Configure `dominus-mcp` in an MCP host.
78
+ - Legacy tool names such as `run_code`, `set_properties`, and `create_ui` are
79
+ replaced by the v2 tool catalog.
80
+ - Dot-separated instance paths are replaced by instance refs containing
81
+ `instanceId` and/or `pathSegments`.
82
+ - Script updates require `expectedRevision` from `studio_read_script`.
83
+ - Existing UI is not replaced unless `replaceExisting: true` is supplied.
84
+
85
+ ## 0.5.5 (2026-04-23)
86
+
87
+ ### New MCP Tools (30 total, up from 24)
88
+
89
+ - **`move_instance`** — Reparent an instance preserving all descendants. Sets ChangeHistoryService waypoint.
90
+ - **`bulk_set_properties`** — Set properties on multiple instances in one call. Explicit paths or className filter mode.
91
+ - **`find_replace_scripts`** — Find and replace across all scripts with optional Lua pattern matching and dry run preview.
92
+ - **`undo`** — Undo last action (ChangeHistoryService). Like Ctrl+Z.
93
+ - **`redo`** — Redo last undone action. Like Ctrl+Y.
94
+
95
+ ### Improvements
96
+
97
+ - **`get_properties` now supports compact mode** — Same filtering as `get_descendants_properties`. Strips read-only, nil, deprecated, and default-valued properties by default. The previous version returned all ~50 properties per instance even though most were noise.
98
+ - **Fixed code injection in `clone_instance`, `group_instances`, `build_multiple`** — Instance names and paths with special characters (quotes, backslashes) no longer break generated Luau code.
99
+ - **`build_multiple` now supports `rgb()` colors and `canCollide`** — Previously only handled `#hex` and BrickColor names; `rgb(255,0,0)` would silently fail.
100
+ - **Better tool descriptions** — More specific descriptions help AI models pick the right tool. `get_properties` disambiguates vs `serialize_ui` and `get_descendants_properties`.
101
+ - **Shared `luaStr()` and `resolvePath()` helpers** — Centralized safe string generation for all code-gen tools.
102
+
103
+ ## 0.5.4 (2026-04-23)
104
+
105
+ ### Fixes
106
+
107
+ - **Rebuilt plugin** — 0.5.3 shipped a stale `Dominus.rbxm` missing the compact property filtering and protocol changes. This release includes the correctly built plugin.
108
+
109
+ ## 0.5.3 (2026-04-23)
110
+
111
+ ### Improvements
112
+
113
+ - **Compact `get_descendants_properties`** — Now strips read-only, nil, deprecated, and default-valued properties by default, reducing response size by ~80%. Pass `compact: false` for the full dump.
114
+ - **`serialize_ui` exposed as MCP tool** — Was previously only in the internal tool registry. Now available to all MCP clients (Copilot, Cursor, Claude, etc.) for converting existing Roblox UI into clean JSON trees.
115
+ - **UI → Roact/React conversion guidance** — System prompt and internal memory now teach the agent the full workflow: `serialize_ui` → JSON tree → Roact/React component with correct type mappings (UDim2, Color3, Vector2, enums, FontFace).
116
+ - **Smarter tool selection** — Agent now prefers `serialize_ui` over `get_descendants_properties` for UI conversion tasks, avoiding context bloat.
117
+
118
+ ## 0.2.1 (2026-02-24)
119
+
120
+ ### New
121
+
122
+ - **Auto-update checker** — On startup, Dominus checks npm for newer versions
123
+ and prints an upgrade notice. Cached for 4 hours, non-blocking, never throws.
124
+
125
+ ### Bug Fixes
126
+
127
+ - **MCP server crashes on EADDRINUSE** — `dominus mcp` would crash if port 18088
128
+ was already held by a running `dominus start` (or another MCP instance). The MCP
129
+ server now checks for an existing listener and connects as a relay client instead
130
+ of trying to bind the same port.
131
+
132
+ ### New MCP Tools (22 total, up from 14)
133
+
134
+ - **`get_class_info`** — Look up the full schema of any Roblox class via
135
+ ReflectionService (properties, methods, events with types).
136
+ - **`create_ui`** — Create an entire UI tree in one call with a declarative JSON
137
+ spec. Auto-coerces UDim2, Color3, Font, and enums. ~10x faster than `run_code`.
138
+ - **`create_part`** — One-call Part creation with position, size, color, material,
139
+ shape, transparency, anchored, and collision settings.
140
+ - **`clone_instance`** — Clone an instance with optional rename, reparent, and
141
+ position offset.
142
+ - **`group_instances`** — Group multiple instances into a Model or Folder.
143
+ - **`build_multiple`** — Batch-create many parts/instances in a single round-trip.
144
+ - **`execute_run_test`** — Enter Run mode via `StudioTestService:ExecuteRunModeAsync()`
145
+ with pass-through args and result capture.
146
+ - **`execute_play_test`** — Enter Play mode via `StudioTestService:ExecutePlayModeAsync()`
147
+ for full client-server simulation tests.
148
+
149
+ ### New CLI Features
150
+
151
+ - **`dominus mcp-install`** — Auto-install MCP config into Cursor, VS Code,
152
+ Claude Desktop, Windsurf, and Claude Code with one command.
153
+ - **`dominus mcp-setup`** — Print manual MCP configuration instructions.
154
+ - **Relay client architecture** — `dominus start` can now connect as a relay
155
+ client to an existing MCP-owned WebSocket server, allowing the TUI and MCP
156
+ to coexist on the same port.
157
+
158
+ ### Plugin Improvements
159
+
160
+ - Enhanced `Properties.lua` with broader property type support.
161
+ - Improved `Reflection.lua` for richer class metadata.
162
+ - Updated `TestRunner.lua` with Run/Play mode test support.
163
+ - New `UIBuilder.lua` module for server-side declarative UI construction.
164
+
165
+ ### Other Changes
166
+
167
+ - Multi-provider AI config improvements (OpenRouter, xAI, Gemini, custom).
168
+ - TUI setup wizard for first-run API key and provider configuration.
169
+ - Improved system prompt with builder-tool awareness.
170
+ - WebSocket server now supports controller relay connections.
171
+
172
+ ## 0.1.0 (2026-02-23)
173
+
174
+ - Initial release — 14 MCP tools, TUI agent, persistent memory, Roblox Studio
175
+ WebSocket bridge.
package/README.md CHANGED
@@ -1,248 +1,164 @@
1
- # Dominus
2
-
3
- **AI-powered autonomous agent for Roblox Studio development.**
4
-
5
- Dominus connects to Roblox Studio over WebSocket, giving you a terminal-based AI assistant that can read scripts, edit code, run Luau, browse the explorer tree, manage instances, upload assets, and run tests -- all in real-time.
6
-
7
- ```
8
- ◆ ◆ ◆
9
- ╔█╗ ╔█╗ ╔█╗
10
- ╔╝ ╚╗ ╔╝ ╚╗ ╔╝ ╚╗
11
- ╚████████████████████████████████╝
12
- D O M I N U S
13
- ```
14
-
15
- ## Features
16
-
17
- - **Autonomous AI Agent** -- Plans, executes, and verifies multi-step tasks using tool calls (not just chat)
18
- - **Real-time Studio Bridge** -- Bidirectional WebSocket connection to Roblox Studio via plugin
19
- - **Persistent Memory** -- SQLite-backed memory that learns your project across sessions
20
- - **15 Built-in Tools** -- Read/edit scripts, run code, browse explorer, manage instances, search, upload assets, run tests
21
- - **Beautiful TUI** -- Ink-powered terminal interface with explorer tree, chat, output log, and live tool indicators
22
- - **Multi-Model Support** -- Use any AI model via OpenRouter (Claude, GPT-4o, Gemini, Llama, DeepSeek, etc.)
23
- - **Open Cloud Integration** -- Upload images, models, and audio directly to Roblox
24
- - **Configurable Rules** -- Tell Dominus what to do and what not to do with persistent rules
25
- - **StudioTestService** -- Run tests directly from the terminal
26
- - **Plugin Auto-Install** -- One command to install the Studio plugin
27
-
28
- ## Quick Start
29
-
30
- ### 1. Install Dominus
31
-
32
- ```bash
33
- # With pnpm (recommended)
34
- pnpm add -g dominus-cli
35
-
36
- # Or with npm
37
- npm install -g dominus-cli
38
- ```
39
-
40
- ### 2. Set Your API Key
41
-
42
- Get an API key from [OpenRouter](https://openrouter.ai/settings/keys) (free tier available):
43
-
44
- ```bash
45
- dominus config set apiKey sk-or-v1-your-key-here
46
- ```
47
-
48
- Or use an environment variable:
49
-
50
- ```bash
51
- export OPENROUTER_API_KEY=sk-or-v1-your-key-here
52
- ```
53
-
54
- ### 3. Install the Studio Plugin
55
-
56
- ```bash
57
- dominus install-plugin
58
- ```
59
-
60
- This copies the Dominus plugin to your Roblox Studio plugins folder. Restart Studio to load it.
61
-
62
- ### 4. Launch Dominus
63
-
64
- ```bash
65
- dominus
66
- ```
67
-
68
- The TUI will start, open a WebSocket server on port 18088, and wait for Studio to connect. In Studio, click the **Dominus > Connect** button in the toolbar.
69
-
70
- ## Configuration
71
-
72
- All config is stored at `~/.dominus/config.json`.
73
-
74
- ```bash
75
- # Set your API key
76
- dominus config set apiKey <key>
77
-
78
- # Change the AI model
79
- dominus config set model openai/gpt-4o
80
-
81
- # Change the WebSocket port
82
- dominus config set port 9090
83
-
84
- # Set your display name
85
- dominus config set userName Eli
86
-
87
- # Set up Open Cloud for asset uploads
88
- dominus config set openCloudApiKey <your-open-cloud-key>
89
-
90
- # View all settings
91
- dominus config list
92
- ```
93
-
94
- ### Available Models
95
-
96
- Any model on [OpenRouter](https://openrouter.ai/models) works. Popular choices:
97
-
98
- | Model | ID |
99
- |---|---|
100
- | Claude Sonnet 4 | `anthropic/claude-sonnet-4` |
101
- | GPT-4o | `openai/gpt-4o` |
102
- | GPT-4o Mini | `openai/gpt-4o-mini` |
103
- | Gemini 2.0 Flash | `google/gemini-2.0-flash-001` |
104
- | DeepSeek V3 | `deepseek/deepseek-chat` |
105
- | Llama 3.3 70B | `meta-llama/llama-3.3-70b-instruct` |
106
-
107
- ## Agent Rules
108
-
109
- Tell Dominus what to do (and what NOT to do):
110
-
111
- ```bash
112
- # Add rules
113
- dominus rules add-do "Always use strict Luau type annotations"
114
- dominus rules add-do "Follow Knit framework patterns"
115
- dominus rules add-dont "Never use deprecated APIs like wait()"
116
- dominus rules add-dont "Don't modify the DataStore schema without asking"
117
-
118
- # View rules
119
- dominus rules list
120
- ```
121
-
122
- Rules persist across sessions at `~/.dominus/rules.json`.
123
-
124
- ## TUI Commands
125
-
126
- Inside the Dominus terminal:
127
-
128
- | Command | Description |
129
- |---|---|
130
- | (just type) | Chat with the AI agent |
131
- | `/help` | Show all commands |
132
- | `/run <code>` | Execute Luau in Studio |
133
- | `/model <id>` | Switch AI model |
134
- | `/clear` | Clear chat history |
135
- | `/status` | Show connection info |
136
- | `/index` | Re-index project scripts |
137
- | `/memory` | Show recalled facts |
138
-
139
- ## Architecture
140
-
141
- ```
142
- ┌─────────────────────────────────────────────────────┐
143
- │ Terminal │
144
- │ ┌─────────────────────────────────────────────────┐ │
145
- │ │ Dominus TUI (Ink/React) │ │
146
- │ │ ┌──────────┐ ┌───────────────────────────────┐ │ │
147
- │ │ │ Explorer │ │ AI Chat + Tool Indicators │ │ │
148
- │ │ │ │ │ │ │ │
149
- │ │ └──────────┘ └───────────────────────────────┘ │ │
150
- │ │ ┌─────────────────────────────────────────────┐
151
- │ │ │ Output Log │ │ │
152
- │ │ └─────────────────────────────────────────────┘ │ │
153
- │ │ ┌─────────────────────────────────────────────┐
154
- │ │ │ > Input │ │ │
155
- │ │ └─────────────────────────────────────────────┘ │ │
156
- │ └─────────────────────────────────────────────────┘
157
- │ │ │
158
- │ ┌──────────┴──────────┐ │
159
- │ │ Agent Loop │ │
160
- │ │ (Plan→Execute→ │ │
161
- │ │ Verify→Learn) │ │
162
- │ └──────────┬──────────┘ │
163
- │ │ │
164
- │ ┌───────────────────┼───────────────────┐ │
165
- │ │ │ │ │
166
- │ ┌──┴──┐ ┌─────┴─────┐ ┌────┴────┐ │
167
- │ │Tools│ │ Memory │ │ AI │ │
168
- │ │(15) │ │ (SQLite) │ │Provider │ │
169
- │ └──┬──┘ └───────────┘ └─────────┘ │
170
- │ │ │
171
- └─────┼────────────────────────────────────────────────┘
172
- │ WebSocket
173
-
174
- ┌─────┴────────────────────────────────────────────────┐
175
- │ Roblox Studio │
176
- │ ┌─────────────────────────────────────────────────┐ │
177
- │ │ Dominus Plugin │ │
178
- │ │ (WS Client → Explorer, Executor, Watcher, │ │
179
- │ │ Properties, Reflection, TestRunner) │ │
180
- │ └─────────────────────────────────────────────────┘ │
181
- └───────────────────────────────────────────────────────┘
182
- ```
183
-
184
- ## Studio Plugin
185
-
186
- The plugin uses the **WebSocket API** introduced in Roblox Studio (October 2025):
187
-
188
- ```lua
189
- HttpService:CreateWebStreamClient(Enum.WebStreamClientType.WebSocket, { Url = "ws://localhost:18088" })
190
- ```
191
-
192
- ### Building with Rojo
193
-
194
- If you have [Rojo](https://rojo.space/) installed:
195
-
196
- ```bash
197
- pnpm build:plugin
198
- ```
199
-
200
- This creates `plugin/Dominus.rbxm` that you can drag into Studio.
201
-
202
- ### Manual Install
203
-
204
- ```bash
205
- dominus install-plugin
206
- ```
207
-
208
- Copies the plugin Lua files directly to your Studio plugins folder.
209
-
210
- ## Development
211
-
212
- ```bash
213
- # Clone and install
214
- git clone https://github.com/eli/dominus.git
215
- cd dominus
216
- pnpm install
217
-
218
- # Run in dev mode
219
- pnpm dev
220
-
221
- # Run tests
222
- pnpm test
223
-
224
- # Type check
225
- pnpm typecheck
226
-
227
- # Build
228
- pnpm build
229
-
230
- # Format
231
- pnpm format
232
- ```
233
-
234
- ## Tech Stack
235
-
236
- - **TypeScript** + **Node.js 20+** -- Runtime
237
- - **Ink 5** (React for CLI) -- Terminal UI framework
238
- - **ws** -- WebSocket server
239
- - **OpenAI SDK** -- AI provider (OpenRouter-compatible)
240
- - **sql.js** -- SQLite in WASM (persistent memory)
241
- - **Commander** -- CLI argument parsing
242
- - **Vitest** -- Test runner
243
- - **tsup** -- Bundler
244
- - **Rojo** -- Roblox plugin builder
245
-
246
- ## License
247
-
248
- MIT
1
+ # Dominus 2
2
+
3
+ Dominus 2 is a secure, MCP-native engineering bridge for Roblox Studio. It gives
4
+ an MCP host direct, typed access to Studio instances, scripts, UI, reflection,
5
+ output, and tests without embedding a second chat model or exposing arbitrary
6
+ Luau execution.
7
+
8
+ ## What changed
9
+
10
+ - MCP-only product: the old Ink chat CLI is no longer published.
11
+ - 17 focused tools with input/output schemas, structured results, and risk hints.
12
+ - Stable instance refs survive dots in names, renames, reparenting, and duplicate
13
+ sibling names for the life of the Studio session.
14
+ - Script writes require a revision from `studio_read_script`.
15
+ - Mutation batches and UI replacement are undoable and roll back on failure.
16
+ - The loopback Studio bridge requires a persistent token and first-use pairing.
17
+ - Multiple Studio windows are selected by unique connection ID, not place ID.
18
+ - Roblox Creator Docs API lookup is built in.
19
+
20
+ ## Requirements
21
+
22
+ - Node.js 20 or newer
23
+ - Roblox Studio with HTTP requests enabled for Studio/plugin use
24
+ - An MCP client such as Codex, Claude Desktop, Cursor, or VS Code
25
+
26
+ Dominus does not require its own AI API key. Your MCP host supplies the model.
27
+
28
+ ## Install
29
+
30
+ Install the npm package globally:
31
+
32
+ ```powershell
33
+ npm install -g dominus-cli@latest
34
+ ```
35
+
36
+ Install or update the Studio plugin:
37
+
38
+ ```powershell
39
+ dominus-install-plugin
40
+ ```
41
+
42
+ Restart Roblox Studio after installing the plugin.
43
+
44
+ ## MCP configuration
45
+
46
+ Add Dominus to your MCP client's server configuration:
47
+
48
+ ```json
49
+ {
50
+ "mcpServers": {
51
+ "dominus": {
52
+ "command": "dominus-mcp"
53
+ }
54
+ }
55
+ }
56
+ ```
57
+
58
+ For a version-pinned configuration that does not require a global install:
59
+
60
+ ```json
61
+ {
62
+ "mcpServers": {
63
+ "dominus": {
64
+ "command": "npx",
65
+ "args": ["-y", "-p", "dominus-cli@2.1.0", "dominus-mcp"]
66
+ }
67
+ }
68
+ }
69
+ ```
70
+
71
+ Restart the MCP client after changing its configuration.
72
+
73
+ ## First connection
74
+
75
+ 1. Start the MCP client so `dominus-mcp` is running.
76
+ 2. Open Roblox Studio. The Dominus 2 plugin connects to `127.0.0.1:18088`.
77
+ 3. On first use, Studio Output prints a connection ID and six-digit pairing code.
78
+ 4. Ask the MCP agent to call `dominus_status`, then `dominus_pair_studio` with
79
+ that connection ID and code.
80
+ 5. Pairing is saved. Future Studio sessions authenticate automatically.
81
+
82
+ If several Studio windows are open, call `dominus_select_studio` with the exact
83
+ connection ID before editing. Two windows on the same place ID remain distinct.
84
+
85
+ ## Agent workflow
86
+
87
+ Dominus instructs MCP hosts to use this loop:
88
+
89
+ 1. Inspect the target tree, selection, instances, scripts, and API references.
90
+ 2. Plan the smallest coherent change and define acceptance checks.
91
+ 3. Apply a transactional mutation or revision-checked script update.
92
+ 4. Read the changed state back.
93
+ 5. Run a Studio test when behavior changed.
94
+
95
+ For UI fidelity work, use `studio_snapshot_ui` after `studio_build_ui` and compare
96
+ fonts, UDim2 values, colors, strokes, and hierarchy rather than relying on a
97
+ successful write response alone.
98
+
99
+ ## Tool catalog
100
+
101
+ Connection tools:
102
+
103
+ - `dominus_status`
104
+ - `dominus_pair_studio`
105
+ - `dominus_select_studio`
106
+
107
+ Studio inspection:
108
+
109
+ - `studio_get_tree`
110
+ - `studio_inspect`
111
+ - `studio_get_selection`
112
+ - `studio_read_script`
113
+ - `studio_snapshot_ui`
114
+ - `studio_get_output`
115
+ - `studio_get_reflection`
116
+
117
+ Studio changes and verification:
118
+
119
+ - `studio_update_script`
120
+ - `studio_apply`
121
+ - `studio_delete_instances`
122
+ - `studio_build_ui`
123
+ - `studio_run_test`
124
+
125
+ Roblox documentation:
126
+
127
+ - `roblox_search_api`
128
+ - `roblox_get_api`
129
+
130
+ ## Security model
131
+
132
+ The MCP transport is stdio. The separate Studio WebSocket bridge binds only to
133
+ `127.0.0.1`, limits messages to one MiB, rate-limits sockets, times out incomplete
134
+ handshakes, and authenticates both Studio plugins and relay controllers. First-use
135
+ pairing requires a code visible in Studio. The plugin only accepts an explicit
136
+ command allowlist and contains no `loadstring` executor.
137
+
138
+ The bridge token protects against accidental or opportunistic access by unrelated
139
+ local processes. Like other user-level credentials, it cannot protect against a
140
+ process that already has permission to read all files in the same user account.
141
+
142
+ ## Development
143
+
144
+ ```powershell
145
+ pnpm install
146
+ pnpm typecheck
147
+ pnpm test
148
+ pnpm build
149
+ pnpm build:plugin
150
+ npm pack --dry-run
151
+ ```
152
+
153
+ Run the MCP server in development:
154
+
155
+ ```powershell
156
+ pnpm dev:mcp
157
+ ```
158
+
159
+ The design and research notes are in
160
+ [`docs/DOMINUS_2_PLAN.md`](docs/DOMINUS_2_PLAN.md).
161
+
162
+ ## License
163
+
164
+ MIT
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env node
2
+ import fs from 'fs';
3
+ import os from 'os';
4
+ import path from 'path';
5
+ import { fileURLToPath } from 'url';
6
+
7
+ function getPluginDirectory() {
8
+ if (process.platform === "win32") {
9
+ const localAppData = process.env.LOCALAPPDATA;
10
+ if (!localAppData) throw new Error("LOCALAPPDATA is not set");
11
+ return path.join(localAppData, "Roblox", "Plugins");
12
+ }
13
+ if (process.platform === "darwin") {
14
+ return path.join(os.homedir(), "Documents", "Roblox", "Plugins");
15
+ }
16
+ return path.join(os.homedir(), ".local", "share", "Roblox", "Plugins");
17
+ }
18
+ var distDirectory = path.dirname(fileURLToPath(import.meta.url));
19
+ var source = path.resolve(distDirectory, "..", "plugin", "Dominus.rbxm");
20
+ var destinationDirectory = getPluginDirectory();
21
+ var destination = path.join(destinationDirectory, "Dominus2.rbxm");
22
+ if (!fs.existsSync(source)) {
23
+ throw new Error(`Packaged plugin not found at ${source}. Run pnpm build:plugin first.`);
24
+ }
25
+ fs.mkdirSync(destinationDirectory, { recursive: true });
26
+ fs.copyFileSync(source, destination);
27
+ console.log(`Installed Dominus 2 Studio plugin to ${destination}`);
28
+ console.log("Restart Roblox Studio, start dominus-mcp, then approve the pairing code shown in Studio Output.");
29
+ //# sourceMappingURL=install-plugin.js.map
30
+ //# sourceMappingURL=install-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/install-plugin.ts"],"names":[],"mappings":";;;;;;AAKA,SAAS,kBAAA,GAA6B;AACpC,EAAA,IAAI,OAAA,CAAQ,aAAa,OAAA,EAAS;AAChC,IAAA,MAAM,YAAA,GAAe,QAAQ,GAAA,CAAI,YAAA;AACjC,IAAA,IAAI,CAAC,YAAA,EAAc,MAAM,IAAI,MAAM,yBAAyB,CAAA;AAC5D,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,YAAA,EAAc,QAAA,EAAU,SAAS,CAAA;AAAA,EACpD;AACA,EAAA,IAAI,OAAA,CAAQ,aAAa,QAAA,EAAU;AACjC,IAAA,OAAO,KAAK,IAAA,CAAK,EAAA,CAAG,SAAQ,EAAG,WAAA,EAAa,UAAU,SAAS,CAAA;AAAA,EACjE;AACA,EAAA,OAAO,IAAA,CAAK,KAAK,EAAA,CAAG,OAAA,IAAW,QAAA,EAAU,OAAA,EAAS,UAAU,SAAS,CAAA;AACvE;AAEA,IAAM,gBAAgB,IAAA,CAAK,OAAA,CAAQ,aAAA,CAAc,MAAA,CAAA,IAAA,CAAY,GAAG,CAAC,CAAA;AACjE,IAAM,SAAS,IAAA,CAAK,OAAA,CAAQ,aAAA,EAAe,IAAA,EAAM,UAAU,cAAc,CAAA;AACzE,IAAM,uBAAuB,kBAAA,EAAmB;AAChD,IAAM,WAAA,GAAc,IAAA,CAAK,IAAA,CAAK,oBAAA,EAAsB,eAAe,CAAA;AAEnE,IAAI,CAAC,EAAA,CAAG,UAAA,CAAW,MAAM,CAAA,EAAG;AAC1B,EAAA,MAAM,IAAI,KAAA,CAAM,CAAA,6BAAA,EAAgC,MAAM,CAAA,8BAAA,CAAgC,CAAA;AACxF;AAEA,EAAA,CAAG,SAAA,CAAU,oBAAA,EAAsB,EAAE,SAAA,EAAW,MAAM,CAAA;AACtD,EAAA,CAAG,YAAA,CAAa,QAAQ,WAAW,CAAA;AACnC,OAAA,CAAQ,GAAA,CAAI,CAAA,qCAAA,EAAwC,WAAW,CAAA,CAAE,CAAA;AACjE,OAAA,CAAQ,IAAI,iGAAiG,CAAA","file":"install-plugin.js","sourcesContent":["import fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nfunction getPluginDirectory(): string {\n if (process.platform === 'win32') {\n const localAppData = process.env.LOCALAPPDATA;\n if (!localAppData) throw new Error('LOCALAPPDATA is not set');\n return path.join(localAppData, 'Roblox', 'Plugins');\n }\n if (process.platform === 'darwin') {\n return path.join(os.homedir(), 'Documents', 'Roblox', 'Plugins');\n }\n return path.join(os.homedir(), '.local', 'share', 'Roblox', 'Plugins');\n}\n\nconst distDirectory = path.dirname(fileURLToPath(import.meta.url));\nconst source = path.resolve(distDirectory, '..', 'plugin', 'Dominus.rbxm');\nconst destinationDirectory = getPluginDirectory();\nconst destination = path.join(destinationDirectory, 'Dominus2.rbxm');\n\nif (!fs.existsSync(source)) {\n throw new Error(`Packaged plugin not found at ${source}. Run pnpm build:plugin first.`);\n}\n\nfs.mkdirSync(destinationDirectory, { recursive: true });\nfs.copyFileSync(source, destination);\nconsole.log(`Installed Dominus 2 Studio plugin to ${destination}`);\nconsole.log('Restart Roblox Studio, start dominus-mcp, then approve the pairing code shown in Studio Output.');\n"]}