Appearance
Synced from the studio-plugin README.
TypeTorch Studio plugin
Attaches Roblox Studio to typetorch serve (tt serve) by itself and keeps it synced: no Connect button, no reconnecting by hand. It also lets an agent drive Studio (reconnect, play, stop, Output), pushes code into a running playtest (kernel 0.5.4+), publishes hot assets from a panel (select a model or UI, Add, then Publish to dev, with no place publish first), pairs with someone else's serve over the internet, and has a Claude window that prompts Claude Code on the serve machine.
Install
GitHub release
Download TypeTorchSync.rbxm from the latest release into Studio's plugins folder (Windows: %LOCALAPPDATA%\Roblox\Plugins, macOS: ~/Documents/Roblox/Plugins), then restart Studio (or reload plugins). Releases are the main channel: every version lands there first.
Creator Store
The plugin is also on the Creator Store. That copy is updated by hand (see Releasing), so it can lag behind the latest GitHub release.
From a checkout
rojo build default.project.json --plugin TypeTorchSync.rbxm (npm run install-plugin; npm run build writes TypeTorchSync.rbxm to the repo instead), or tt studio install-plugin --from <this folder>. The plugin is not on npm.
Then run tt serve in the game folder: the plugin finds it. The CLI's README ("Studio: typetorch serve") describes the whole loop.
The panel
The toolbar's TypeTorch button opens the dock widget (its icon follows the connection state once the icon ids in Icons.luau are set). Cards, top to bottom:
- Status: waiting, connecting, synced, disconnected or paused; the attached project and its ports, the last sync. Once a sync drops it stays Disconnected (red dot) with how long ago, retrying by itself, until serve is back; each (re)connect rescans the hot assets and runs a quiet Check against that serve. Reconnect starts over (a full resync); Auto-connect: on/off (per place); Connect anyway shows when the only serve found is for another experience.
- Server: which serve this Studio uses (this computer's, or a paired remote). The pairing link box is always there: paste a new link and Pair to switch, or Use this computer's serve to go back from a remote.
- Playtest: Live playtest: on/off. On, the playtest's server syncs code into the running game and the kernel (0.5.4+) reloads on changes, with no Stop + Play.
- Hot assets: the hot assets marked in the place and what the last check found. Add marks the Explorer selection (the name box sets the key; with one hot asset selected, a new name turns Add into Rename), Remove unmarks it. Check compares the place with the lockfile, Upload uploads new and changed assets, Publish to dev (named after serve's dev branch:
dev, ortt serve --dev-branch <b>) uploads and deploys them to that branch. Each button shows only when it has work; they send the open place's export to serve as a job. After a check, each new, changed or removed row has a Diff button (CLI 0.15.0+): the instances added, removed or changed inside it. While the panel is open the check repeats every 30 s (below). - Compile: the last compile result and its first errors.
- typetorch serve: serve's child processes and their restarts.
In Play the toolbar and windows stay (on the client in Play, the server in Run); a playtest's panel shows only status, playtest and compile, since pairing and hot assets act on the edit session.
Releasing
npm version <x.y.z> -m "release %s" && git push origin main --follow-tags, after setting VERSION in src/TypeTorch/App.luau (the version the panel shows) to the same number. The tag runs .github/workflows/release.yml (nothing else does: no PR or branch runs): it checks the tag against package.json, builds TypeTorchSync.rbxm with the Rojo that rokit.toml pins, and publishes the GitHub release with the rbxm attached (a version with -, like -rc.1, is a prerelease).
For a stable version the roblox job then tries to update the Creator Store asset through Open Cloud (.github/scripts/roblox-upload.sh): the rbxm, then the description (.github/store-description.txt plus the version, the date and the commits since the previous tag). It reads only the GitHub environment roblox: secret ROBLOX_API_KEY (an Open Cloud key with the Assets API, Read + Write, owned by the asset's creator), variable ROBLOX_PLUGIN_ASSET_ID. Without them it skips with a notice.
Open Cloud doesn't take Plugin assets from API keys yet ("TargetType Plugin is not supported yet"), so today that job only warns, writes the manual steps to the run summary and stays green. Publishing to Roblox is manual: download the release's TypeTorchSync.rbxm, drag it into a place in Studio, right-click it in the Explorer, Publish as Plugin, and overwrite the existing asset (135066807179101). The job starts uploading by itself once Roblox supports it.
Working with someone else's serve
The owner runs tt serve --remote. serve opens a gateway on localhost:34890 and a free Cloudflare quick tunnel to it (cloudflared is installed when missing), then prints a one-time pairing link: the tunnel URL with the code after a #, like https://<name>.trycloudflare.com#<code>, valid 15 minutes (tt serve status shows it again, tt serve pair makes a new one; with --url <tunnel> or --no-tunnel the owner uses their own tunnel and tt serve pair --url).
Paste the whole link into the panel's Server card and press Pair (or Enter). The plugin splits it on the last #, sends the code with your Roblox user id and name to <url>/tt/pair, and keeps the device token it gets back in its settings; a bare code without a URL pairs with a serve --remote on this machine (http://localhost:34890). Studio then syncs from that serve (code read-only, Rojo at <url>/r/<token>) and the Hot assets buttons run there. The pairing lasts 30 days on the owner's side (tt serve devices, tt serve unpair). Use this computer's serve goes back to the local serve (the pairing stays valid until the owner unpairs it). See the CLI's README ("A Studio on another machine").
Claude
The toolbar's Claude button opens a chat with Claude Code on the machine that runs tt serve --claude (remote-claude from @typetorch/dev-server), a port of the in-game DEV > Claude tab. It works with a local serve and with a paired remote one, through serve's /tt/claude/... routes; replies stream over serve's WebSocket (/tt/claude/stream), with HTTP polling while there is no stream. Only allowed Roblox users can prompt: serve's --claude-users <ids>, by default the owners in typetorch.json. A remote Studio prompts as the user it paired with, so the owner adds a helper's id there (pair again after updating the plugin, so serve knows your user). Each dev has their own worktree on the serve machine (dev-server 0.4.0), so several devs can use it at once.
- Code mode from Studio: Claude edits a copy of the serve machine's branch. The Live / Code pill shows the mode; Live (game tools on a running server) works from the in-game tab.
- The open place: the plugin answers Claude's
inspect,find,game_logs(Studio output) andgame_status, read-only, in Edit. Only prompts sent from this chat are answered (src/TypeTorch/StudioTools.luau). Claude changes the game through files (Code mode, above), never by running code in Studio: the plugin doesn't execute code it receives (Creator Store rules ban runtime code loading), sorun_luauis answered "not available in Studio" (0.7.1 removed it). Planned: the requests come from remote-claude (dev-server 0.4.0) through serve's/tt/claude/v1, which doesn't pass/v1/game/*through yet (CLI 0.18.1), so until it does Claude works from the files only. - "+" menu for the next message: Dex path (the Studio selection), My logs (this DataModel's Output), Server logs and Screenshot (in Play only), Toolbox (Creator Store tools for that message only).
- New chat; tap the status line for recent chats; the copy icon on a reply selects its Markdown for Ctrl+C. Images Claude shows are drawn in the chat. The chat is kept on serve per user, so it follows you between Edit and Play.
- Apply this change? When a run changed files, remote-claude commits them and the reply ends in a card with the summary and the changed files (+/- lines). Apply and Deploy to dev need dev-server 0.4.0, which is not on npm yet;
tt serve --claudefrom CLI 0.12.2 on needs it to start at all (0.3.3 refuses--deploy-branch):- Apply (green) puts the change into the checkout serve's Rojo syncs to Studio, uncommitted, so you review and commit it there. A change to lines that changed there too is refused and the checkout is left as it was.
- Deploy to dev runs
typetorch deployof that commit to serve's dev branch; the card shows "Deploying...", "Waiting for approval on your PC" when the deploy needs the owner's approval, then "Deployed" with the build id (or why it failed). Running dev servers hot-swap to it. - Discard drops the commit.
- With no answer in 15 minutes the change is discarded. Only the user who sent the prompt can decide. A card whose change was lost to a restart of serve or remote-claude says so.
Layout
The control API's contract is src/serve/protocol.ts in typetorch/cli; the two must change together.
src/Main.server.luau: the plugin script.src/TypeTorch/App.luau: finds the server (GET /tt/helloon 34880-34887, one port at a time so Studio asks for HTTP permission only for ports a serve uses:Control.discover), picks the one whose universeId matches the place, runs Rojo's sync, reconnects, reports to the server. In a playtest's server it syncs into the running game and setsServerStorage.TypeTorchDev'sLiveReloadattribute, which makes the kernel (0.5.4+) reload on changes.src/TypeTorch/Agent.luau: in every DataModel (edit, playtest server and client): runs the commands an agent sends throughtypetorch studio/typetorch mcp(long poll on/tt/plugin/poll), forwards Studio's Output, and in edit mode reconnects when theTypeTorchReconnectattribute is set on ServerStorage.src/TypeTorch/Assets.luau: hot assets in the place (add, remove, the sync's rules) and their export from the open place (SerializationService, the same format as the CLI's export task); the panel's Check / Upload / Publish to dev buttons send that export totypetorch serveas a job (POST /tt/jobs,assets status|sync --studio-export). While the panel is open and a serve is attached, the check also runs by itself every 30 s (never while a job runs, never with nothing marked): the export is made and compared with the last check's, and only a changed place or lockfile reaches serve. A check's answer (CLI 0.15.0+) carries a diff per new, changed or removed asset:Assets.describeDiffturns it into the lines behind each row's Diff button (instances added, removed, changed with old and new property values; an older serve sends none and the button stays hidden).src/TypeTorch/Icons.luau: the toolbar icons asrbxassetid://<id>: the TypeTorch button's per connection state (gray waiting, amber connecting, green synced, red disconnected) and the Claude button's. Their PNGs are inassets/icons/;bun scripts/upload-icons.ts --user <id> [--env-file <game repo>/.env](or--group <id>) uploads them as Images with an Open Cloud assets key and fills the ids in. An empty id keeps Studio's default icon.src/TypeTorch/Panel.luau,Widgets.luau: the dock widget, in the TypeTorch dev menu's look.src/TypeTorch/Claude.luau: the Claude window (/tt/claude/...on serve, which talks to remote-claude).src/TypeTorch/StudioTools.luau: Claude's game tools on the open place, for prompts from this chat (Edit only).src/TypeTorch/Control.luau: the control API client (clisrc/serve/protocol.tsis the contract): a local port, or a paired remote serve (its URL plus a device token; Rojo at<url>/r/<token>).vendor/rojo/: Rojo's plugin core, unchanged except where marked.assets/toolbar-icon.png(32 px) andtoolbar-icon@2x.png(64 px): the TypeTorch logo for the toolbar button. Upload the 32 px one as an image asset and put itsrbxassetid://inTOOLBAR_ICON(Panel.luau). The logo's source isbrand/in typetorch/docs.
Rojo (vendored, MPL-2.0)
vendor/rojo/ is the plugin core of Rojo 7.7.0-rc.1 (the version rokit.toml pins in TypeTorch games), so it speaks the same protocol as rojo serve: plugin/src without the Roact UI (App/), assets, sounds, tests and its entry script, plus its packages http, log, fmt, rbx_dom_lua (without allValues.json, used only by tests), Promise and t. Those files are under the Mozilla Public License 2.0 (vendor/rojo/LICENSE.txt); Promise and t keep their own licenses next to them.
Changed files (MPL-2.0 still applies to them, and each says what changed at its top):
Plugin/Settings.lua: no Roact (getBinding/getBindingsremoved); settings are stored asTypeTorchRojo_<name>so they never mix with the stock Rojo plugin's.
To update Rojo: copy the same files from the new tag, re-apply the change above, and keep Version.txt in step with the rojo that rokit.toml pins.
License
MIT (LICENSE), except vendor/rojo/ (MPL-2.0, see above).