Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/studio-connect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"contentrain": minor
---

Add `studio connect` command that links a local repository to a Contentrain Studio project in one interactive flow — workspace selection, GitHub App installation, repo detection, `.contentrain/` scanning, and project creation. Also fixes the validate integration test timeout by batching 80 sequential git-branch spawns into a single `git update-ref --stdin` call.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@ npx contentrain validate # check content health
npx contentrain generate # generate typed SDK client
npx contentrain status # project overview
npx contentrain doctor # setup health check
npx contentrain studio login # authenticate with Studio
npx contentrain studio connect # connect repo to Studio project
```

## Documentation
Expand Down
9 changes: 9 additions & 0 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,15 @@ When the local CLI and MCP flow are not enough, [Contentrain Studio](/studio) ad
- media management
- CDN delivery for non-web platforms

Connect your local project to Studio with two commands:

```bash
contentrain studio login
contentrain studio connect
```

The `connect` command detects your git remote, verifies GitHub App installation, scans for `.contentrain/` configuration, and creates the project — all in one interactive flow. See [CLI Studio Integration](/packages/cli#connecting-a-repository) for details.

## The Content Pipeline

Every operation follows the same governance pipeline:
Expand Down
25 changes: 25 additions & 0 deletions docs/packages/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ Requirements:
| `contentrain generate` | Generate `.contentrain/client/` and `#contentrain` package imports |
| `contentrain diff` | Review and merge or reject pending `contentrain/*` branches |
| `contentrain serve` | Start the local review UI or the MCP stdio server |
| `contentrain studio connect` | Connect a repository to a Studio project |
| `contentrain studio login` | Authenticate with Contentrain Studio |
| `contentrain studio logout` | Log out from Studio |
| `contentrain studio whoami` | Show current authentication status |
Expand Down Expand Up @@ -311,6 +312,30 @@ contentrain studio logout

Credentials are stored in `~/.contentrain/credentials.json` with `0o600` permissions — never inside the project directory. For CI/CD, set the `CONTENTRAIN_STUDIO_TOKEN` environment variable to skip interactive login.

### Connecting a Repository

```bash
# Interactive flow: workspace → GitHub App → repo → scan → create project
contentrain studio connect

# Skip workspace selection
contentrain studio connect --workspace ws-123
```

The `connect` command links your local repository to a Studio project in one interactive flow:

1. **Workspace** — select an existing workspace (auto-selects if only one)
2. **GitHub App** — checks if the Contentrain GitHub App is installed; if not, opens the browser for installation
3. **Repository** — detects the current git remote and matches it against accessible repos
4. **Scan** — checks the repository for `.contentrain/` configuration, reports found models and locales
5. **Create** — prompts for a project name and creates the project in Studio

After a successful connection, workspace and project IDs are saved as defaults so subsequent `studio` commands skip interactive selection.

::: tip Run `contentrain init` First
The connect flow works best when `.contentrain/` is already initialized and pushed to the repository. The scan step confirms your setup, but you can also connect first and initialize later.
:::

### CDN Setup & Delivery

```bash
Expand Down
11 changes: 11 additions & 0 deletions docs/studio.md
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,17 @@ So the split is:
- **open-source Contentrain** = local, Git-native content governance core
- **Contentrain Studio** = team operations and delivery layer for the same content contract

## Connecting from the CLI

The fastest way to create a Studio project from an existing repository is the CLI `connect` command:

```bash
contentrain studio login
contentrain studio connect
```

This single interactive flow handles workspace selection, GitHub App installation, repository detection, `.contentrain/` scanning, and project creation. See the [CLI Studio Integration](/packages/cli#connecting-a-repository) section for the full step-by-step.

## Go Deeper

- [Ecosystem Map](/ecosystem)
Expand Down
10 changes: 9 additions & 1 deletion packages/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ Requirements:
| `contentrain generate` | Generate `.contentrain/client/` and `#contentrain` package imports |
| `contentrain diff` | Review and merge or reject pending `contentrain/*` branches |
| `contentrain serve` | Start the local review UI or the MCP stdio server |
| `contentrain studio connect` | Connect a repository to a Studio project |
| `contentrain studio login` | Authenticate with Contentrain Studio |
| `contentrain studio logout` | Log out from Studio |
| `contentrain studio whoami` | Show current authentication status |
Expand Down Expand Up @@ -172,11 +173,18 @@ to understand:

The `studio` command group connects the CLI to [Contentrain Studio](https://studio.contentrain.io) for enterprise workflows.

Authenticate:
Authenticate and connect:

```bash
contentrain studio login
contentrain studio whoami
contentrain studio connect
```

The `connect` command links your local repository to a Studio project. It detects the git remote, verifies GitHub App installation, scans for `.contentrain/` configuration, and creates the project — all in one interactive flow.

```bash
contentrain studio connect --workspace ws-123
```

Set up CDN for content delivery:
Expand Down
36 changes: 36 additions & 0 deletions packages/cli/src/studio/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ import {
type ActivityEntry,
type UsageMetrics,
type PaginatedResponse,
type GitHubInstallation,
type GitHubRepo,
type GitHubSetupUrl,
type ScanResult,
type CreateProjectPayload,
} from './types.js'

// ── Client ────────────────────────────────────────────────────────────────
Expand Down Expand Up @@ -163,6 +168,37 @@ export class StudioApiClient {
return this.request<Project[]>('GET', `/api/workspaces/${workspaceId}/projects`)
}

// ── GitHub / Connect ───────────────────────────────────────────────────

async createProject(workspaceId: string, payload: CreateProjectPayload): Promise<Project> {
return this.request<Project>('POST', `/api/workspaces/${workspaceId}/projects`, {
body: payload,
})
}

async listGitHubInstallations(): Promise<GitHubInstallation[]> {
return this.request<GitHubInstallation[]>('GET', '/api/github/installations')
}

async getGitHubSetupUrl(): Promise<GitHubSetupUrl> {
return this.request<GitHubSetupUrl>('GET', '/api/github/setup')
}

async listGitHubRepos(installationId: number): Promise<GitHubRepo[]> {
return this.request<GitHubRepo[]>('GET', '/api/github/repos', {
query: { installationId: String(installationId) },
})
}

async scanRepository(installationId: number, repoFullName: string): Promise<ScanResult> {
return this.request<ScanResult>('GET', '/api/github/scan', {
query: {
installationId: String(installationId),
repo: repoFullName,
},
})
}

// ── Branches ──────────────────────────────────────────────────────────

async listBranches(wid: string, pid: string): Promise<Branch[]> {
Expand Down
Loading
Loading