Protocol route reference
The canonical Studio Backend Protocol route table (protocol version 1), from
@jxsuite/protocol
. The dev server is the reference implementation; any backend serving these shapes can host Studio. Optional routes back optional platform-adapter members — Studio degrades without them as described.
Session / project
| Route | Method | Path | Summary | Optional | Degradation |
|---|---|---|---|---|---|
activate |
POST | /__studio/activate |
Bind the backend to a project root | no | — |
project |
GET | /__studio/project |
Root project metadata {name, root} | no | — |
projectInfo |
GET | /__studio/project-info |
Probe a directory: {isSiteProject, projectConfig?, directories?} | no | — |
resolveSite |
GET | /__studio/resolve-site |
Resolve the owning site of a file path {sitePath, projectConfig?, fileRelPath?} | no | — |
sites |
GET | /__studio/sites |
Enumerate site projects [{config, path}] (backs listProjects) | yes | The welcome screen's Projects catalogue stays hidden. |
findProject |
GET | /__studio/find-project |
Locate a project directory by name outside the root | yes | openProject falls back to config-matching only. |
locateDirectory |
GET | /__studio/locate-directory |
Resolve the absolute path of a showDirectoryPicker() folder by the id in its .jx-loc-id | yes | The New Project Location field loses its Browse… button and is typed by hand. |
createProject |
POST | /__studio/create-project |
Scaffold a project at a caller-chosen destination → {root, config} | no | — |
starters |
GET | /__studio/starters |
Starter templates (StarterInfo[]) | yes | The New Project picker offers only blank/templates. |
importSite |
POST | /__studio/import-site |
Clone a live website into a project; streams NDJSON progress | yes | The New Project Import tab is unavailable. |
Filesystem
| Route | Method | Path | Summary | Optional | Degradation |
|---|---|---|---|---|---|
files |
GET | /__studio/files |
List a directory (DirEntry[]); with ?glob=
|
no | — |
fileRead |
GET | /__studio/file |
Read a file's text content | no | — |
fileWrite |
PUT | /__studio/file |
Write a file's text content | no | — |
fileDelete |
DELETE | /__studio/file |
Delete a file | no | — |
fileUpload |
POST | /__studio/file/upload |
Upload binary content to a path | no | — |
fileRename |
POST | /__studio/file/rename |
Rename/move (+ refactor report) | no | — |
locate |
POST | /__studio/locate |
Find a file by name → {path | null} | no | — |
collab |
GET | /__studio/collab |
Realtime co-editing: a WebSocket upgrade speaking the @jxsuite/collab wire envelope (one socket per project, documents multiplexed by path; y-protocols sync + project-level awareness in lib0 binary frames — see @jxsuite/collab/envelope for the frame layout and the docEpoch/doc-reset lifecycle). A plain GET (no Upgrade) answers {collab: true, version} as the capability probe. | yes | Realtime co-editing is unavailable; Studio edits solo with file-level saves |
Documents / components / formats
| Route | Method | Path | Summary | Optional | Degradation |
|---|---|---|---|---|---|
components |
GET | /__studio/components |
Discover components (ComponentMeta[]) | no | — |
cem |
GET | /__studio/cem |
Custom-elements manifest of an npm dependency | yes | Dependency components lose prop/slot metadata. |
formats |
GET | /__studio/formats |
The project's format registry entries plus a sibling
extensions
array — per enabled extension its manifest identity and project-section contributions (ExtensionsInfo[]; backs listFormats and listExtensions). |
yes | Only .json documents open (backs listFormats); descriptor-contributed settings sections do not appear. |
projectSchemas |
GET | /__studio/project-schemas |
The project's generated entry documents (project.schema.json / document.schema.json), PRE-BUNDLED into self-contained schemas — {project, document} (backs fetchProjectSchemas). Regenerated on demand when missing or older than project.json. | yes | The JSON editor falls back to the bundled core schemas (extension sections get no editor validation/completion). |
format |
POST | /__studio/format |
Dispatch a format capability {format, action: parse|serialize, source?|doc?} | yes | Non-JSON documents cannot be parsed/serialized (backs formatAction). |
pluginSchema |
GET | /__studio/plugin-schema |
Extract a $studio schema from a class source | yes | Plugin property panels fall back to generic JSON editing. |
codeFormat |
POST | /__studio/code/format |
Format posted source {code, path?} → {code, errors} | yes | Code editors skip format-on-open/save (codeService returns null). |
codeMinify |
POST | /__studio/code/minify |
Minify posted source {code} → {code} | yes | Compiled-output minification is skipped. |
codeLint |
POST | /__studio/code/lint |
Lint posted source {code, path?} → {diagnostics} | yes | Code editors show no lint markers. |
Packages
| Route | Method | Path | Summary | Optional | Degradation |
|---|---|---|---|---|---|
packages |
GET | /__studio/packages |
List dependencies (PackageInfo[]) | no | — |
packagesAdd |
POST | /__studio/packages/add |
Add a dependency | no | — |
packagesRemove |
POST | /__studio/packages/remove |
Remove a dependency | no | — |
packagesInstall |
POST | /__studio/packages/install |
Run the package manager install | yes | Install/reinstall affordances are hidden; manifest-only edits still work. |
packagesNeedsInstall |
GET | /__studio/packages/needs-install |
Whether node_modules is stale | yes | The install-on-open prompt never shows. |
packagesOutdated |
GET | /__studio/packages/outdated |
Dependencies with newer versions (OutdatedInfo[]) | yes | The update affordances are hidden. |
packagesSetVersions |
POST | /__studio/packages/set-versions |
Rewrite dependency ranges and install | yes | Bulk version updates are hidden. |
Git
| Route | Method | Path | Summary | Optional | Degradation |
|---|---|---|---|---|---|
gitStatus |
GET | /__studio/git/status |
Working-tree status (GitStatusResult) | no | — |
gitBranches |
GET | /__studio/git/branches |
Branch list (GitBranchesResult) | no | — |
gitLog |
GET | /__studio/git/log |
Recent commits (GitLogEntry[]) | no | — |
gitStage |
POST | /__studio/git/stage |
Stage files | no | — |
gitUnstage |
POST | /__studio/git/unstage |
Unstage files | no | — |
gitCommit |
POST | /__studio/git/commit |
Commit staged (else all dirty) files | no | — |
gitPush |
POST | /__studio/git/push |
Push (cloud: sync check — commits land on push) | no | — |
gitPull |
POST | /__studio/git/pull |
Pull/fast-forward; 409 {conflicts} on overlap | no | — |
gitFetch |
POST | /__studio/git/fetch |
Refresh remote tracking state | no | — |
gitCheckout |
POST | /__studio/git/checkout |
Switch branches | no | — |
gitCreateBranch |
POST | /__studio/git/create-branch |
Create a branch | no | — |
gitDiff |
GET | /__studio/git/diff |
Unified diff of dirty files (or one path) | no | — |
gitShow |
GET | /__studio/git/show |
File content at a ref | no | — |
gitDiscard |
POST | /__studio/git/discard |
Discard working changes | no | — |
gitInit |
POST | /__studio/git/init |
Initialize a repository | no | — |
gitAddRemote |
POST | /__studio/git/add-remote |
Add a remote | no | — |
gitClone |
POST | /__studio/git/clone |
Clone a repository | yes | The welcome screen hides Clone Git Repository. |
gitPr |
POST | /__studio/git/pr |
Open a pull request → PullRequestInfo | yes | Studio falls back to a direct GitHub API call with the user's token. |
Data surface (connector domain owner console)
| Route | Method | Path | Summary | Optional | Degradation |
|---|---|---|---|---|---|
dataConnections |
GET | /__studio/data/connections |
Connector connections with configured/missingSecrets/isDefault state, reachable table names, and registry-descriptor provider metadata (DataConnectionsResponse; backs dataConnections) | yes | The connections settings section shows no status, and data-domain actions stay hidden. |
dataConnectionTest |
POST | /__studio/data/connections/test |
Probe a connection {connection} → DataConnectionTestResult (backs dataConnectionTest) | yes | The Test Connection action is hidden. |
dataPush |
POST | /__studio/data/push |
Additive schema push {connection?, dryRun?} → DataPushResult (plan of DataPushStep[], applied, warnings/errors; backs dataPush) | yes | The Push Schema action is hidden; schemas deploy via
jx db push
instead. |
dataRows |
GET | /__studio/data/rows |
Page a table (DataRowsQuery params) → DataRowsResult {rows, total, columns} (backs dataRows) | yes | The data grid is unavailable. |
dataInsertRow |
POST | /__studio/data/rows |
Insert a row {table, connection?, values} → {row} (backs dataInsertRow) | yes | The data grid hides its add-row footer. |
dataUpdateRow |
PUT | /__studio/data/rows |
Update a row keyed on its primary key {table, connection?, pk, set} → {row} (backs dataUpdateRow) | yes | Data grid cells are read-only. |
dataDeleteRow |
DELETE | /__studio/data/rows |
Delete a row (?table=&pk=&connection=) → {ok} (backs dataDeleteRow) | yes | The data grid hides row deletion. |
Secrets (names only)
| Route | Method | Path | Summary | Optional | Degradation |
|---|---|---|---|---|---|
secretsList |
GET | /__studio/secrets |
Configured secret env-var NAMES, never values (SecretsListResponse; backs listSecrets) | yes | Secret fields cannot show set/unset state. |
secretsSet |
PUT | /__studio/secrets |
Write/remove secrets in the backend store (.dev.vars locally) {set?, remove?} → names (backs setSecrets) | yes | The secret form control renders disabled; secrets are edited in .dev.vars by hand. |
AI proxy
| Route | Method | Path | Summary | Optional | Degradation |
|---|---|---|---|---|---|
aiChat |
POST | /__studio/ai/chat |
StreamEvent SSE chat proxy {messages, tools, systemPrompt, model} | no | — |
aiModels |
GET | /__studio/ai/models |
Model catalogue (AiModelsResponse) | no | — |
Cloudflare publish surface
| Route | Method | Path | Summary | Optional | Degradation |
|---|---|---|---|---|---|
cfProxy |
POST | /__studio/cf/proxy |
Allowlisted Cloudflare API passthrough {path, method?, body?} (backs cfApi) | yes | The Publish panel explains the git-push publishing path instead. |