diff --git a/README.md b/README.md
index f39ec440..bef7a89b 100644
--- a/README.md
+++ b/README.md
@@ -1,46 +1,278 @@
-

+
-**Rojo** is a tool designed to enable Roblox developers to use professional-grade software engineering tools.
-
-With Rojo, it's possible to use industry-leading tools like **Visual Studio Code** and **Git**.
-
-Rojo is designed for power users who want to use the best tools available for building games, libraries, and plugins.
+**Atlas** bridges Roblox Studio with **Cursor/Claude**, so large teams can collaborate on complex games with full project context.
## Features
-Rojo enables:
-* Working on scripts and models from the filesystem, in your favorite editor
-* Versioning your game, library, or plugin using Git or another VCS
-* Streaming `rbxmx` and `rbxm` models into your game in real time
-* Packaging and deploying your project to Roblox.com from the command line
+- **Live Sync** — Work on scripts and models from the filesystem with real-time sync to Roblox Studio
+- **Two-Way Sync** — Push changes from the filesystem to Studio, or pull changes from Studio back to the filesystem
+- **Build & Upload** — Package and deploy `.rbxl`, `.rbxm`, `.rbxlx`, and `.rbxmx` files from the command line
+- **Syncback** — Pull an entire Roblox place into a local project with one command
+- **Clone** — Create a full local project from any existing Roblox place: `atlas clone PLACEID`
+- **Cursor / VS Code Extension** — JSON5 schema support, automatic CLI installation, bundled Luau tooling
-In the future, Rojo will be able to:
+## Installation
-* Sync instances from Roblox Studio to the filesystem
-* Automatically convert your existing game to work with Rojo
-* Import custom instances like MoonScript code
+The fastest way to get started is to install the Cursor or VS Code extension, which handles CLI installation automatically.
-## [Documentation](https://rojo.space/docs)
-Documentation is hosted in the [rojo.space repository](https://github.com/rojo-rbx/rojo.space).
+### 1. Install the Extension
-## Contributing
-Check out our [contribution guide](CONTRIBUTING.md) for detailed instructions for helping work on Rojo!
+- **Cursor / Other**: [Open VSX Registry](https://open-vsx.org/extension/UserGeneratedLLC/vscode-roblox-atlas)
+- **VS Code**: [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=UserGeneratedLLC.vscode-roblox-atlas)
-Pull requests are welcome!
+The extension will prompt to install the Atlas CLI via [Rokit](https://github.com/rojo-rbx/rokit) and the Roblox Studio plugin if they aren't already on your system.
-Rojo supports Rust 1.88 and newer. The minimum supported version of Rust is based on the latest versions of the dependencies that Rojo has.
+### 2. Alternative: Manual CLI Install
-## License
-Rojo is available under the terms of the Mozilla Public License, Version 2.0. See [LICENSE.txt](LICENSE.txt) for details.
+If you prefer not to use the extension, install the CLI directly:
+
+**Via Rokit (recommended):**
+```bash
+rokit add --global UserGeneratedLLC/rojo atlas
+```
+
+**Build from source:**
+```bash
+git clone --recursive https://github.com/UserGeneratedLLC/rojo
+cd rojo
+cargo build --release
+```
+
+The binary is output to `target/release/atlas` (or `atlas.exe` on Windows).
+
+## Getting Started
+
+### Clone an Existing PlaceId
+
+```bash
+atlas clone 123456789 # Download and set up the project locally
+atlas serve # Start live sync server for Roblox Studio
+```
+
+Then just:
+
+```bash
+atlas studio # Open the project in Roblox Studio
+atlas cursor # Open the project in Cursor IDE
+```
+
+## New Project
+
+```bash
+atlas init --kind place
+atlas serve
+```
+
+Then in Roblox Studio, open the Atlas plugin widget and click **Connect**.
+
+## CLI Commands
+
+### Core
+
+```bash
+atlas serve [project] # Start live sync server (default port: 34873)
+atlas serve --port 8080 # Use a custom port
+atlas build [project] -o out.rbxl # Build to .rbxl, .rbxm, .rbxlx, or .rbxmx
+atlas build --watch -o out.rbxl # Rebuild automatically on file changes
+atlas build --plugin Plugin.rbxm # Build directly to Studio's plugins folder
+atlas upload [project] --asset_id ID # Upload to Roblox (cookie or API key auth)
+```
+
+### Project Management
+
+```bash
+atlas init # Initialize a new place project
+atlas init --kind model # Initialize a model project
+atlas init --kind plugin # Initialize a plugin project
+atlas clone PLACEID # Clone a Roblox place into a new local project
+atlas fmt-project [project] # Reformat project file with sorted keys
+```
+
+### Syncback
+
+```bash
+atlas syncback [project] # Sync from a local .rbxl to the filesystem
+atlas syncback -d PLACEID # Download the place from Roblox first
+atlas syncback --incremental # Preserve existing file structure
+atlas syncback --list # Preview what will change (no writes)
+atlas syncback --dry-run # Simulate without writing files
+atlas syncback --sourcemap # Generate sourcemap.json after sync
+```
+
+`atlas pull` is an alias for `atlas syncback`.
+
+### Tooling
+
+```bash
+atlas sourcemap [project] # Generate sourcemap.json for Luau LSP
+atlas sourcemap --watch # Regenerate on file changes
+atlas plugin install # Install the Studio plugin
+atlas plugin uninstall # Remove the Studio plugin
+atlas studio [project] # Open the project in Roblox Studio
+atlas cursor [path] # Open the project in Cursor IDE
+atlas doc # Open documentation in the browser
+```
+
+### Global Options
+
+```bash
+atlas --verbose # Enable debug logging (-v, -vv, -vvv)
+atlas --color never # Disable colored output (auto | always | never)
+```
+
+## Workflows
+
+### Cloning from an Existing Place
+
+```bash
+atlas clone 123456789
+```
+
+What happens:
+1. Fetches the experience name from the Roblox API
+2. Creates a project folder with a sanitized name
+3. Initializes the project with `atlas init`
+4. Downloads the place and runs syncback to write all instances to the filesystem
+5. Commits the result if git was initialized
+
+### Updating from Roblox
+
+If the place has been edited in Studio and you want to pull those changes back:
+
+```bash
+atlas syncback -d PLACEID
+```
+
+Or if you already have a local `.rbxl` file:
+
+```bash
+atlas syncback
+```
+
+Use `--incremental` to preserve your existing file layout, or omit it for a clean rebuild. Use `--list` or `--dry-run` to preview before committing to changes.
+
+### Shortcuts
+
+| Command | What it does |
+|---------|-------------|
+| `atlas studio` | Opens the project's place in Roblox Studio (reads `servePlaceIds` from the project file) |
+| `atlas cursor` | Opens the project directory in Cursor IDE |
+
+## One-Shot Mode
+
+One-Shot Sync is a plugin setting (enabled by default) that performs a single sync and then disconnects. When enabled:
+
+- The project tree syncs once, then the plugin automatically disconnects
+- All automatic outgoing writes are blocked — only changes you explicitly confirm are applied
+- The sync lock is skipped, so any number of people can connect and work together simultaneously
+- A 30-second safety timeout ensures the connection is cleaned up
+
+To use persistent (continuous) sync instead, disable "One-Shot Sync" in the plugin settings.
+
+## Working with Teams
+
+Atlas includes a sync lock to prevent conflicts when multiple people work on the same place in Team Create.
+
+- A session lock (`__Atlas_SessionLock` in `ServerStorage`) is acquired when someone connects in persistent mode
+- Only one user can actively sync at a time — others see a message indicating who holds the lock
+- **One-shot mode bypasses the lock**, letting the whole team preview the synced state without conflicts
+
+**Recommended team workflow:** One designated person syncs in persistent mode (one-shot disabled). Everyone else uses one-shot mode for quick, conflict-free previews.
+
+## File Formats
+
+### Scripts
+
+| Extension | Result | RunContext |
+|-----------|--------|-----------|
+| `*.luau` | ModuleScript | — |
+| `*.server.luau` | Script | Server |
+| `*.client.luau` | Script | Client |
+| `*.plugin.luau` | Script | Plugin |
+| `*.local.luau` | LocalScript | — |
+| `*.legacy.luau` | Script | Legacy |
+
+### Data & Models
+
+| Extension | Result |
+|-----------|--------|
+| `*.json5` | ModuleScript (Lua table) |
+| `*.toml` | ModuleScript (Lua table) |
+| `*.yaml` / `*.yml` | ModuleScript (Lua table) |
+| `*.csv` | LocalizationTable |
+| `*.txt` | StringValue |
+| `*.rbxm` | Binary model |
+| `*.rbxmx` | XML model |
+| `*.model.json5` | JSON model |
+
+### Metadata & Projects
+
+| Extension | Purpose |
+|-----------|---------|
+| `*.meta.json5` | Add properties/attributes to a sibling instance |
+| `*.project.json5` | Project file (or nested project) |
+
+Legacy `.lua`, `.json`, `.meta.json`, `.model.json`, and `.project.json` extensions are still supported.
+
+## Project Structure
+
+A typical Atlas place project:
+
+```
+MyGame/
+├── default.project.json5 # Project configuration
+├── src/ # Instance tree (synced to DataModel)
+│ ├── ReplicatedStorage/
+│ ├── ServerScriptService/
+│ ├── ServerStorage/
+│ ├── StarterGui/
+│ ├── StarterPlayer/
+│ └── Workspace/
+├── rokit.toml # Pins Atlas version for the project
+└── .luaurc # Luau LSP configuration
+```
+
+Example `default.project.json5`:
+
+```json5
+{
+ name: "MyGame",
+ servePlaceIds: [123456789],
+ tree: {
+ $className: "DataModel",
+ $path: "src"
+ }
+}
+```
+
+## Troubleshooting
+
+### Plugin not connecting
+- Ensure `atlas serve` is running
+- Check that the port matches (default: `34873`, or whatever `servePort` is set to in your project file)
+- Verify the Atlas CLI version matches the plugin version (major.minor must agree)
+
+### Syncback produces unexpected results
+- Use `--list` or `--dry-run` to preview changes before writing
+- Try `--incremental` to preserve your existing file structure
+- Check `syncbackRules` in your project file for ignored paths or classes
+
+### Build errors
+- Run `atlas fmt-project` to fix JSON formatting issues
+- Ensure all `$path` entries in the project file point to existing files/directories
+
+### Plugin shows "another user is syncing"
+- Someone else holds the sync lock in Team Create
+- Wait for them to disconnect, or use one-shot mode to preview without locking
diff --git a/src/cli/clone.rs b/src/cli/clone.rs
index 5bcbb3e3..1c7ac103 100644
--- a/src/cli/clone.rs
+++ b/src/cli/clone.rs
@@ -36,6 +36,10 @@ pub struct CloneCommand {
/// Skip cloning cursor rules into .cursor directory.
#[clap(long)]
pub skip_rules: bool,
+
+ /// Skip changing the working directory into the project after creation.
+ #[clap(long)]
+ pub skip_cd: bool,
}
impl CloneCommand {
@@ -72,6 +76,7 @@ impl CloneCommand {
skip_git,
placeid: Some(self.placeid),
skip_rules: self.skip_rules,
+ skip_cd: true,
};
init.run()?;
@@ -111,6 +116,11 @@ impl CloneCommand {
.status();
}
+ if !self.skip_cd {
+ std::env::set_current_dir(&path)
+ .with_context(|| format!("Failed to cd into {}", path.display()))?;
+ }
+
Ok(())
}
}
diff --git a/src/cli/init.rs b/src/cli/init.rs
index 792518fb..47dad03a 100644
--- a/src/cli/init.rs
+++ b/src/cli/init.rs
@@ -9,7 +9,7 @@ use std::{
io::{self, Write},
};
-use anyhow::{bail, format_err};
+use anyhow::{bail, format_err, Context};
use clap::Parser;
use fs_err as fs;
use fs_err::OpenOptions;
@@ -45,6 +45,10 @@ pub struct InitCommand {
/// Skip cloning cursor rules into .cursor directory.
#[clap(long)]
pub skip_rules: bool,
+
+ /// Skip changing the working directory into the project after creation.
+ #[clap(skip)]
+ pub skip_cd: bool,
}
impl InitCommand {
@@ -206,8 +210,9 @@ impl InitCommand {
println!("Created project successfully.");
- if self.placeid.is_some() {
- println!("Run 'atlas syncback' to sync your place.");
+ if !self.skip_cd {
+ std::env::set_current_dir(&base_path)
+ .with_context(|| format!("Failed to cd into {}", base_path.display()))?;
}
Ok(())