# Share a world

One world for the team: everyone clones from it, everyone pushes to it.

This page supplies an executable walkthrough for `packages/cli/src/journeys/tutorials.test.ts`.

A shared world is a world with no app in front of it, served on a URL. It holds the team's
history the way a bare repository does, and every developer's world points at it as origin. This
page runs one on your machine; put it behind TLS on a hostname and nothing else changes.

## The app

```json file=package.json
{ "name": "acme-web", "private": true, "type": "module", "dependencies": { "@octokit/rest": "^21" } }
```

The app declares the credential it reads. The World issues a throwaway token for its GitHub account,
`world`; that account is separate from the platform org `acme`. The seed creates `world/web` through
Octokit before any issue is written. It can run again without creating a second repository.

```text file=.env.example
GITHUB_TOKEN=
```

```js file=.volter/seed.ts
import { Octokit } from '@octokit/rest';
const github = new Octokit({ auth: process.env.GITHUB_TOKEN });
const { data: { login: owner } } = await github.users.getAuthenticated();
try {
  await github.repos.get({ owner, repo: 'web' });
} catch (error) {
  if (error.status !== 404) throw error;
  await github.repos.createForAuthenticatedUser({ name: 'web' });
}
```

```js file=file-issue.mjs
import { Octokit } from '@octokit/rest';
const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN });
const { data: issue } = await octokit.issues.create({ owner: 'world', repo: 'web', title: process.argv[2] ?? 'Launch checklist' });
console.log(`filed #${issue.number}`);
```

```bash
npm install
npm install -g @volter/world
npm install -D @volter/twin-github
volter world init
volter world up
```

```text
acme-web  1 twin up, story loaded
```

## The shared world

`init --bare` makes a world with no app: a name, a branch tree per twin, and nothing else.
`serve` puts it on a port and prints the token that opens it. The token is a credential for the
world, never a vendor key; keep it where you keep any team secret.

```text file=../team/.env.example
GITHUB_TOKEN=
```

```js file=../team/.volter/seed.ts
import '../../acme-web/.volter/seed.ts';
```

```bash
cd ../team
volter world init --bare acme/team --twins github
volter world up
volter world down
volter world serve --port 4300 &
```

```text
serving  acme/team  http://127.0.0.1:4300/acme/team
token    tok_
```

Back in the app:

```bash
cd ../acme-web
```

## Point your world at it, and push

`remote add` records the URL and the token, once. `push` sends the entries your world has that
the shared world does not, as a changeset, and moves your base past them.

```bash
volter remote add origin http://127.0.0.1:4300/acme/team --token "$(cat ../team/.volter/token)"
volter world pull
volter world run -- node file-issue.mjs
volter world changeset -m "The launch checklist"
volter world push
```

```text
filed #1
changeset  the-launch-checklist  2 changes
pushed  the-launch-checklist  2 changes → origin
```

## A teammate clones

The shared World has the repository as initial data, too: local seed data is not part of a push. A second app directory stands in for a teammate's laptop. `clone` records the origin and brings
its whole history in, so the teammate's world holds the issue you filed before they run anything.

```bash
mkdir ../acme-web-two && cp package.json file-issue.mjs .env.example ../acme-web-two/ && cd ../acme-web-two
npm install
volter world init
volter world clone http://127.0.0.1:4300/acme/team --token "$(cat ../team/.volter/token)"
volter world up
volter world log
```

```text
cloned  http://127.0.0.1:4300/acme/team  16 changes
github   issue.opened   issue:1
```

The clone includes the shared account and repository setup. A changeset groups the application's unpushed mutations.
They push too, and you pull:

```bash
volter world run -- node file-issue.mjs "Rotate the keys"
volter world changeset -m "Key rotation"
volter world push
cd ../acme-web
volter world pull
volter world log
```

```text
filed #2
pushed  key-rotation  2 changes → origin
pulled  origin  2 changes
github   issue.opened   issue:1
github   issue.opened   issue:2
```

`pull` brings in what origin has that you do not and moves your base past it. Your own unpushed
entries stay where they are, on top of the moved base.

## The shared world's own log

The shared world is a world. Its log is the team's history, and it answers the same verbs.

```bash
cd ../team
volter world log
cd ../acme-web
```

```text
github   issue.opened   issue:1
github   issue.opened   issue:2
```

## Clean up

```bash
volter world down
kill %1
```

## When the shared world should reach the vendor

A shared world is also where a twin's root can be set to the vendor, so that entries landing there
are deployed with a credential no laptop holds. That is [deploy from a shared world](./deploy-from-a-shared-world.md).
