nylorun 0.4.0-beta → 0.6.0-beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +39 -0
- package/README.md +207 -105
- package/dist/cli.js +24 -22
- package/dist/doctor.d.ts +10 -8
- package/dist/doctor.js +54 -37
- package/dist/home.d.ts +1 -1
- package/dist/home.js +1 -1
- package/dist/project/derived-key.d.ts +2 -2
- package/dist/project/derived-key.js +2 -2
- package/dist/project/link.d.ts +7 -7
- package/dist/project/link.js +3 -3
- package/dist/stack/commands.d.ts +23 -15
- package/dist/stack/commands.js +332 -214
- package/dist/stack/compose-file.d.ts +11 -8
- package/dist/stack/compose-file.js +54 -21
- package/dist/stack/docker.d.ts +10 -0
- package/dist/stack/docker.js +64 -1
- package/dist/stack/env-file.d.ts +12 -2
- package/dist/stack/env-file.js +13 -3
- package/dist/stack/host-files.d.ts +4 -4
- package/dist/stack/host-files.js +3 -3
- package/dist/stack/images.d.ts +4 -2
- package/dist/stack/images.js +3 -2
- package/dist/stack/index.d.ts +4 -3
- package/dist/stack/index.js +10 -4
- package/dist/stack/paths.d.ts +3 -3
- package/dist/stack/paths.js +1 -1
- package/dist/stack/ports.d.ts +4 -2
- package/dist/stack/ports.js +3 -1
- package/dist/stack/prepare.d.ts +7 -3
- package/dist/stack/prepare.js +5 -3
- package/dist/stack/proxy.d.ts +78 -0
- package/dist/stack/proxy.js +224 -0
- package/dist/stack/stacks.d.ts +37 -34
- package/dist/stack/stacks.js +91 -57
- package/dist/stack/studio-login.d.ts +4 -3
- package/dist/stack/studio-login.js +5 -4
- package/dist/stack/versions.d.ts +1 -1
- package/dist/stack/versions.js +1 -1
- package/dist/telemetry.d.ts +31 -0
- package/dist/telemetry.js +79 -0
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,44 @@
|
|
|
1
1
|
# nylorun
|
|
2
2
|
|
|
3
|
+
## 0.6.0-beta
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 0cbd5c9: **Breaking (`nylorun`): readable Docker names, several Tenants on one machine, and Studio at `http://<name>.localhost:4160`.** See MIGRATION.md.
|
|
8
|
+
|
|
9
|
+
- **Breaking (`nylorun`): names.** Every container, the network and every volume carries the Tenant's Compose project: containers `nylorun-<name>-postgres`, `-restate`, `-s2-lite`, `-gateway`, `-runtime`, `-studio` (were `…-1`), network `nylorun-<name>` (was `nylorun-<name>_default`), volumes `nylorun-<name>-postgres`, `-restate`, `-s2-lite`, `-workspaces` (were `nylorun-<name>_postgres`, …), each labelled `dev.nylorun.tenant: <name>`. The Compose service `s2` is now `s2-lite` (`nylorun logs s2-lite`).
|
|
10
|
+
- **Breaking (`nylorun`): Tenants created by 0.5 start fresh.** `start` on a Tenant whose data is in the old volumes exits 3 without starting it and names them; `nylorun reset --tenant <name>` starts it anew. `reset` and `delete` also remove the old volumes and the old network.
|
|
11
|
+
- **Studio proxy.** One Caddy container per machine (`nylorun-proxy`, files in `~/.nylorun/proxy/`) gives each Tenant's Studio the address `http://<name>.localhost:<port>` (`NYLORUN_PROXY_PORT`, 4160 or a free port chosen once), on `127.0.0.1` and `[::1]` (IPv4 only, saying so, when Docker refuses `::1`). It holds no Tenant data and routes browsers only. `start` brings it up when Studio starts, prints Studio's proxy URL and signs in there (on Studio's own port when the proxy does not answer); a proxy failure never fails `start`. `status` shows both URLs, `ls` and `nylorun studio` the proxy's. `NYLORUN_PROXY_DISABLED=1` turns it off; a Tenant under `NYLORUN_HOME` or `NYLORUN_COMPOSE_PROJECT` does not use it. `doctor` has a `proxy` row.
|
|
12
|
+
- **Several Tenants.** Restate's RocksDB memory is capped at 256 MiB, so a Tenant uses about 600–700 MB (was about 1.3 GB). `nylorun ls` has a `MEMORY` column (`memoryBytes` in `--json`). `start` names the other running Tenants and their memory. `nylorun stop --all` stops every running Tenant and the proxy, keeping their volumes.
|
|
13
|
+
- **`@nylorun/studio`.** `NYLORUN_STUDIO_PUBLIC_ORIGINS` lists exact `http:` origins Studio also serves (Host and `Origin` checks); a login token's URL is on the origin it was minted on; `NYLORUN_STUDIO_SESSION_COOKIE` names the session cookie (default `nylorun_studio_session`; `nylorun` sets `nylorun_studio_<name>`, so Studios on one host keep their own sessions); the `421` answer lists the served origins.
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- Pin runtime to the tested release.
|
|
18
|
+
- Pin studio to the tested release.
|
|
19
|
+
|
|
20
|
+
## 0.5.0-beta
|
|
21
|
+
|
|
22
|
+
### Minor Changes
|
|
23
|
+
|
|
24
|
+
- f96fe32: **Studio reports anonymous page views, unless you opt out.** Studio sends page views to Google Analytics with every Tenant, agent and session id replaced by `:id` and the query dropped; nothing sent to agents is collected. `nylorun start` says so once, and passes the measurement id to the Studio container as `NYLORUN_STUDIO_ANALYTICS_ID`. Turn it off with `nylorun telemetry disable`, `NYLORUN_TELEMETRY_DISABLED=1` or `DO_NOT_TRACK=1`; it is always off in CI, inside an embedding app, and when the browser sends Do Not Track or Global Privacy Control.
|
|
25
|
+
- 4b9906f: **Breaking: "Tenant" replaces "stack", and `nylorun start` works anywhere.** Each local installation holds one Tenant, and its name is the Tenant's name, so help, output, errors and docs say Tenant. See MIGRATION.md.
|
|
26
|
+
|
|
27
|
+
- **Breaking (`nylorun`): selection.** Every command acts on the Tenant `--tenant <name>` names (replaces `--name`, which is removed), else `NYLORUN_TENANT` (replaces `NYLORUN_STACK`), else the Project link's `tenant`; `start` in a project names a new one after the project directory. Outside a project, or with `start --no-link`, commands act on the Tenant `default`. In a project without a link, commands other than `start` exit 2 and list the machine's Tenants. A name starting with `tn_` (a Tenant id) is refused.
|
|
28
|
+
- **Breaking (`nylorun`): files.** Host roots are under `~/.nylorun/tenants/<name>/` (was `~/.nylorun/stacks/<name>/`) with `tenant.json` (was `stack.json`); the `.env` key is `NYLORUN_TENANT_NAME` (was `NYLORUN_STACK_NAME`); `NYLORUN_COMPOSE_PROJECT` replaces `NYLORUN_STACK_PROJECT`. Compose projects stay `nylorun-<name>`. Every command first moves 0.4 Host roots from `~/.nylorun/stacks/` to `~/.nylorun/tenants/` (renaming `stack.json` and the `.env` key), so they keep their volumes and keys. `nylorun ls` lists only directories with `tenant.json`.
|
|
29
|
+
- **Breaking (`nylorun`): removed.** `nylorun legacy` and all handling of the single stack of releases before 0.4; the hidden `nylorun stack <cmd>` alias; `nylorun doctor stack|runtime`. Output says Tenant: `ls` prints `TENANT` and JSON `{ "tenants": [...] }`, `status` prints the Tenant id on its own line, and `doctor`'s row is `tenant`.
|
|
30
|
+
- **Breaking: Project link format 3.** `.nylorun/link.json` is `{ "format": 3, "tenant", "tenantId", "hostUrl", "hostId" }`; `tenant` replaces `stack`. `@nylorun/agents`, `@nylorun/cli` and `@nylorun/admin` refuse an older link and name `npx nylorun start`, which rewrites it. `@nylorun/core`'s `ProjectLinkFileSchema` parses formats 0–3 with `tenant`.
|
|
31
|
+
- **Breaking (`@nylorun/admin`):** `createAdmin({ tenant })` replaces `{ stack }`, `tenantHostRoot(name)` replaces `stackHostRoot(name)`, and local resolution reads `NYLORUN_TENANT` and the link's `tenant`.
|
|
32
|
+
- `@nylorun/cli`: `status` and `endpoints` drop the `stack` line and JSON key; messages say Tenant. `@nylorun/agents`: a Runtime too old for the client says "update the Runtime (npx nylorun@latest start)". `@nylorun/studio`: setup hints say Tenant. `@nylorun/create-agent`: the next steps describe `npx nylorun@beta start` as this project's Tenant and its link.
|
|
33
|
+
|
|
34
|
+
### Patch Changes
|
|
35
|
+
|
|
36
|
+
- Pin core to the tested release.
|
|
37
|
+
- Pin runtime to the tested release.
|
|
38
|
+
- Pin studio to the tested release.
|
|
39
|
+
- Updated dependencies [4b9906f]
|
|
40
|
+
- @nylorun/core@0.11.0-beta
|
|
41
|
+
|
|
3
42
|
## 0.4.0-beta
|
|
4
43
|
|
|
5
44
|
### Major Changes
|
package/README.md
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
# nylorun
|
|
2
2
|
|
|
3
|
-
Sets up and runs local Nylorun
|
|
4
|
-
Compose
|
|
3
|
+
Sets up and runs local Nylorun Tenants: the Runtime and Studio, in Docker
|
|
4
|
+
Compose, one Tenant per project. It needs nothing in your project; run it with
|
|
5
5
|
`npx` in the project's directory:
|
|
6
6
|
|
|
7
7
|
```sh
|
|
8
|
-
npx nylorun start # create (first run) and start this project's
|
|
8
|
+
npx nylorun start # create (first run) and start this project's Tenant, and the Project link
|
|
9
9
|
npx nylorun stop # stop it; volumes (and the Tenant's data) are kept
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
-
A
|
|
13
|
-
S2, serving exactly
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
[`@nylorun/cli`](../cli/README.md) (command `nylo`).
|
|
19
|
-
only among Nylorun packages and never imports
|
|
20
|
-
[runtime/src/CONTEXT.md](../runtime/src/CONTEXT.md).
|
|
12
|
+
A local Tenant is one installation: one Runtime with its own Postgres, Restate
|
|
13
|
+
and S2, serving exactly that Tenant, and its name is the Tenant's name.
|
|
14
|
+
`nylorun start` in a project creates the project's Tenant (the Runtime creates
|
|
15
|
+
it on its first start) and links the project to it; anywhere else, it starts
|
|
16
|
+
the Tenant `default`. Projects that must not share agents, credentials or
|
|
17
|
+
history run separate Tenants. Agents, sessions and model providers belong to
|
|
18
|
+
the Runtime client, [`@nylorun/cli`](../cli/README.md) (command `nylo`).
|
|
19
|
+
Depends on `@nylorun/core` only among Nylorun packages and never imports
|
|
20
|
+
`@nylorun/runtime`. Vocabulary: [runtime/src/CONTEXT.md](../runtime/src/CONTEXT.md).
|
|
21
21
|
|
|
22
22
|
Prerequisites, installed by the developer (nylorun never downloads them): Node
|
|
23
23
|
24 or newer, and Docker with Compose v2 ([Docker
|
|
@@ -28,53 +28,93 @@ another engine). On Windows, install them inside
|
|
|
28
28
|
supported.
|
|
29
29
|
|
|
30
30
|
```sh
|
|
31
|
-
npx nylorun doctor # Node 24+, Docker, Compose v2, and the
|
|
31
|
+
npx nylorun doctor # Node 24+, Docker, Compose v2, and the Tenant's health
|
|
32
32
|
```
|
|
33
33
|
|
|
34
34
|
## Commands
|
|
35
35
|
|
|
36
36
|
```sh
|
|
37
|
-
nylorun up|start [--
|
|
38
|
-
# create (first run) and start the
|
|
39
|
-
nylorun down|stop [--
|
|
40
|
-
nylorun status [--
|
|
41
|
-
nylorun logs [service] [--
|
|
42
|
-
nylorun studio [--
|
|
43
|
-
nylorun reset [--
|
|
44
|
-
nylorun ls [--json] # the
|
|
45
|
-
nylorun delete <
|
|
46
|
-
nylorun
|
|
47
|
-
nylorun
|
|
37
|
+
nylorun up|start [--tenant <name>] [--no-link] [--no-studio] [--no-open] [--allow-downgrade] [--studio-embed-origin <origin>]... [--studio-embed-origin-reset]
|
|
38
|
+
# create (first run) and start the Tenant; link the project; print the URLs; open Studio signed in
|
|
39
|
+
nylorun down|stop [--tenant <name> | --all] # stop the containers (--all: every Tenant's, and the Studio proxy); keep volumes
|
|
40
|
+
nylorun status [--tenant <name>] [--json] # the Tenant, its Host root and id, services, endpoints, Runtime health
|
|
41
|
+
nylorun logs [service] [--tenant <name>] [-f] [--tail <n>] # postgres, restate, s2-lite, gateway, runtime, studio
|
|
42
|
+
nylorun studio [--tenant <name>] [--no-open] # sign a browser in to Studio on the Tenant; starts it if needed
|
|
43
|
+
nylorun reset [--tenant <name>] [--yes] # delete the Tenant's volumes, Tenant directory and vault key; the next start creates it anew
|
|
44
|
+
nylorun ls [--json] # the Tenants on this machine, with their state, memory and URLs
|
|
45
|
+
nylorun delete <tenant> --yes # remove a Tenant: containers, volumes, Host root and vault key
|
|
46
|
+
nylorun doctor [--json] # prerequisites and the Tenant's health
|
|
47
|
+
nylorun telemetry [status|enable|disable] # Studio's anonymous usage analytics
|
|
48
48
|
```
|
|
49
49
|
|
|
50
50
|
`up` and `down` are the Docker Compose spellings of `start` and `stop`: `down`
|
|
51
|
-
stops the containers and keeps the volumes, so no Tenant data is lost.
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
Tenant; `nylorun status|reset`, or `nylo status|reset|endpoints`), `nylorun
|
|
55
|
-
dev`, `nylorun configure`, `nylorun status --env` and `nylorun doctor sandbox`.
|
|
51
|
+
stops the containers and keeps the volumes, so no Tenant data is lost. Removed
|
|
52
|
+
commands exit 2 naming the replacement: `nylorun dev`, `nylorun configure`,
|
|
53
|
+
`nylorun status --env` and `nylorun doctor sandbox`.
|
|
56
54
|
|
|
57
|
-
##
|
|
55
|
+
## Tenants
|
|
58
56
|
|
|
59
|
-
Every command acts on one
|
|
57
|
+
Every command acts on one Tenant, chosen in this order:
|
|
60
58
|
|
|
61
|
-
1. `--
|
|
62
|
-
2. `
|
|
63
|
-
3. the
|
|
59
|
+
1. `--tenant <name>`;
|
|
60
|
+
2. `NYLORUN_TENANT`;
|
|
61
|
+
3. the Tenant in the project's link (`.nylorun/link.json`, found from the
|
|
64
62
|
working directory upwards);
|
|
65
|
-
4. for `start` in a project
|
|
66
|
-
|
|
67
|
-
|
|
63
|
+
4. for `start` in a project: the project directory's name, lowercased, with
|
|
64
|
+
characters outside `[a-z0-9_-]` as `-`, and a suffix (`-2`, `-3`, …) when a
|
|
65
|
+
Tenant of that name was created for another project directory;
|
|
66
|
+
5. outside a project, or `start --no-link`: the Tenant `default`.
|
|
67
|
+
|
|
68
|
+
In a project without a link, the commands other than `start` exit 2 and list
|
|
69
|
+
the Tenants on this machine. A name is lowercase letters, digits, `-` and `_`;
|
|
70
|
+
a Tenant id (`tn_…`) is refused: pass the Tenant's name (`nylorun ls` lists
|
|
71
|
+
them).
|
|
72
|
+
|
|
73
|
+
Each Tenant has its own Host root `~/.nylorun/tenants/<name>/`, Compose project
|
|
74
|
+
`nylorun-<name>` (`NYLORUN_COMPOSE_PROJECT` overrides it), volumes, network and
|
|
75
|
+
ports. `NYLORUN_HOME` replaces the whole Host root (the Tenant's name then
|
|
76
|
+
comes from its `tenant.json`, the project directory or the Host root's own
|
|
77
|
+
name). nylorun 0.4 kept Host roots in `~/.nylorun/stacks/`: the first command
|
|
78
|
+
of this release moves them to `~/.nylorun/tenants/`, keeping their Compose
|
|
79
|
+
projects and volumes.
|
|
80
|
+
|
|
81
|
+
### Several Tenants
|
|
82
|
+
|
|
83
|
+
Tenants run side by side, each on its own ports, containers, network and
|
|
84
|
+
volumes ([The containers](#the-containers)); a running Tenant uses about
|
|
85
|
+
600–700 MB. Each Studio has its own address through the
|
|
86
|
+
[Studio proxy](#the-studio-proxy), `http://<name>.localhost:4160`. `nylorun ls`
|
|
87
|
+
lists them with their state, the memory their containers use (`MEMORY`: the sum
|
|
88
|
+
of `docker stats` over the containers labelled `dev.nylorun.tenant=<name>`, `-`
|
|
89
|
+
when stopped; `memoryBytes` in `--json`, `null` when stopped or unknown), the
|
|
90
|
+
Runtime's URL and Studio's:
|
|
91
|
+
|
|
92
|
+
```text
|
|
93
|
+
TENANT STATE MEMORY RUNTIME STUDIO PROJECT
|
|
94
|
+
api running 652 MB http://localhost:8790 http://api.localhost:4160 /Users/me/api
|
|
95
|
+
default stopped - http://localhost:8787 http://default.localhost:4160 -
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
When other Tenants are running, `start` says so after its summary, on stderr
|
|
99
|
+
(without the size when Docker does not report it):
|
|
68
100
|
|
|
69
|
-
|
|
70
|
-
|
|
101
|
+
```text
|
|
102
|
+
Also running: default, api (about 1.3 GB). "nylorun stop --all" stops them all.
|
|
103
|
+
```
|
|
71
104
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
from its `stack.json`, the project directory or the Host root's own name).
|
|
105
|
+
`nylorun stop --all` stops every running Tenant on this machine and the Studio
|
|
106
|
+
proxy, keeping their volumes; it cannot be combined with `--tenant` (exit 2).
|
|
107
|
+
`stop` of one Tenant leaves the proxy running.
|
|
76
108
|
|
|
77
|
-
A
|
|
109
|
+
A Tenant created by nylorun 0.5 keeps its data in volumes Compose named
|
|
110
|
+
`<project>_postgres`, `<project>_restate`, `<project>_s2` and
|
|
111
|
+
`<project>_workspaces`; this release names them `<project>-postgres`, … (see
|
|
112
|
+
[The containers](#the-containers)). `start` on such a Tenant exits 3 without
|
|
113
|
+
starting it, naming the old volumes: run `nylorun reset --tenant <name>` to
|
|
114
|
+
start it fresh. `reset` and `delete` also remove the old volumes (and the old
|
|
115
|
+
network `<project>_default`).
|
|
116
|
+
|
|
117
|
+
A Tenant refuses only a Runtime older than its own database: `start` records
|
|
78
118
|
the pinned Runtime version in `host.json` (`runtimeVersion`) and exits 5 when
|
|
79
119
|
this nylorun pins an older one. Update nylorun, or pass `--allow-downgrade`
|
|
80
120
|
when both versions use the same database schema (otherwise the Runtime reports
|
|
@@ -84,105 +124,165 @@ recorded version.
|
|
|
84
124
|
|
|
85
125
|
## The Project link
|
|
86
126
|
|
|
87
|
-
`nylorun start` in a project waits until the
|
|
127
|
+
`nylorun start` in a project waits until the Tenant is open
|
|
88
128
|
(`/v1/admin/status`), then writes, in a `.nylorun/` directory (mode 0700, with
|
|
89
129
|
its own `.gitignore` of `*`):
|
|
90
130
|
|
|
91
|
-
- `link.json`: `{ "format":
|
|
92
|
-
|
|
131
|
+
- `link.json`: `{ "format": 3, "tenant", "tenantId", "hostUrl", "hostId" }`.
|
|
132
|
+
`tenant` is the local Tenant's name; the Tenant id is information only:
|
|
133
|
+
nothing in a request selects a Tenant.
|
|
93
134
|
- `credentials.json` (mode 0600): the key of the derived principal `project`,
|
|
94
|
-
derived from the
|
|
135
|
+
derived from the Tenant's admin key, and its id.
|
|
95
136
|
|
|
96
|
-
Later starts reuse the
|
|
97
|
-
Host or
|
|
137
|
+
Later starts reuse the Tenant and rewrite the link only when the Tenant's name,
|
|
138
|
+
URL, Host or id changed (after `nylorun reset`, for example). When it writes a
|
|
98
139
|
new link, `start` seeds the Tenant from the project's `.env`: the sandbox
|
|
99
140
|
backend (`NYLORUN_SANDBOX=auto|virtual`) and the model credential
|
|
100
141
|
(`MODEL_PROVIDER`, `MODEL`, `MODEL_PROVIDER_API_KEY`, `MODEL_PROVIDER_BASE_URL`,
|
|
101
142
|
or `.nylorun/auth.json`), unless the Tenant has a model or
|
|
102
|
-
`NYLORUN_DEV_MODEL=fixture`. `.env` never configures the
|
|
143
|
+
`NYLORUN_DEV_MODEL=fixture`. `.env` never configures the containers.
|
|
103
144
|
|
|
104
145
|
A fresh clone or a second worktree has no link: `nylorun start` there creates a
|
|
105
|
-
new
|
|
106
|
-
both share
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
stack and replaces the link.
|
|
146
|
+
new Tenant, or `nylorun start --tenant <name>` attaches it to an existing one so
|
|
147
|
+
both share it. `--no-link` starts a Tenant without linking the working
|
|
148
|
+
directory (scripts). A link of an older nylorun (format 0 to 2) counts as no
|
|
149
|
+
link: `start` replaces it.
|
|
110
150
|
|
|
111
151
|
The Runtime registers the derived principals of `NYLORUN_DERIVED_PRINCIPALS`
|
|
112
|
-
(comma-separated, from the environment of `nylorun start`, kept in the
|
|
152
|
+
(comma-separated, from the environment of `nylorun start`, kept in the Tenant's
|
|
113
153
|
`.env`) when it creates the Tenant; `project` is always among them.
|
|
114
154
|
|
|
115
|
-
## The
|
|
155
|
+
## The containers
|
|
116
156
|
|
|
117
157
|
`nylorun start` writes `compose.yaml` and `.env` (mode 0600) under
|
|
118
|
-
`~/.nylorun/
|
|
119
|
-
|
|
120
|
-
|
|
158
|
+
`~/.nylorun/tenants/<name>/docker/` on every start; `.env` keeps the ports and
|
|
159
|
+
secrets chosen on the first run. The services are `postgres`, `restate`,
|
|
160
|
+
`s2-lite`, `gateway`, `runtime` and `studio`. Container, network and volume
|
|
161
|
+
names are global on the Docker engine, so each carries the Tenant's Compose
|
|
162
|
+
project, and each has the label `dev.nylorun.tenant: <name>`. For Tenant `shop`:
|
|
163
|
+
|
|
164
|
+
| Thing | Name |
|
|
165
|
+
| --- | --- |
|
|
166
|
+
| Containers | `nylorun-shop-postgres`, `nylorun-shop-restate`, `nylorun-shop-s2-lite`, `nylorun-shop-gateway`, `nylorun-shop-runtime`, `nylorun-shop-studio` |
|
|
167
|
+
| Network | `nylorun-shop` |
|
|
168
|
+
| Volumes | `nylorun-shop-postgres`, `nylorun-shop-restate`, `nylorun-shop-s2-lite`, `nylorun-shop-workspaces` |
|
|
169
|
+
|
|
170
|
+
Postgres initialises the Tenant's database with C collation. Restate's RocksDB
|
|
171
|
+
memory is capped at 256 MiB (`RESTATE_ROCKSDB_TOTAL_MEMORY_SIZE`; Restate's
|
|
172
|
+
default is 2 GiB), so several Tenants fit on a laptop: a Tenant uses about
|
|
173
|
+
600–700 MB, down from about 1.3 GB. The Runtime and Studio images are pinned by
|
|
121
174
|
this release (`package.json` `nylorun.runtime` and `nylorun.studio`);
|
|
122
175
|
`NYLORUN_RUNTIME_IMAGE` and `NYLORUN_STUDIO_IMAGE` override them (local builds,
|
|
123
176
|
CI). Ports publish on loopback only: the Runtime on `8787`, its operator
|
|
124
177
|
listener (Admin API) on `8788`, Studio on `4161` and the Restate UI on `9070`,
|
|
125
|
-
or free ports chosen on the
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
`start`
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
and
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
178
|
+
or free ports chosen on the Tenant's first start, avoiding the ports other
|
|
179
|
+
Tenants and the Studio proxy keep, and kept in its `.env`.
|
|
180
|
+
|
|
181
|
+
`start`, `ls` and `nylorun studio` give Studio as `http://<name>.localhost:4160`,
|
|
182
|
+
its address through the Studio proxy (below); `status` adds Studio's own
|
|
183
|
+
`http://localhost:<port>` (`--json` has both: `studio.url` is Studio's own port,
|
|
184
|
+
which an embedding app frames, and `studio.proxyUrl` the proxy's). Studio has no
|
|
185
|
+
password: in a terminal (not in CI, and not with `--no-open`), `start` asks the
|
|
186
|
+
Studio container for a single-use login token with the admin key (`POST
|
|
187
|
+
/_studio/login-tokens`, through the proxy; on Studio's own port, saying so,
|
|
188
|
+
when the proxy does not answer) and opens `…/login?token=…` on the Tenant's
|
|
189
|
+
page in the browser. That sets a session cookie for 30 days, which survives
|
|
190
|
+
Studio restarts, so the printed URL keeps working in that browser. The token
|
|
191
|
+
itself is never printed unless no browser starts. Otherwise `start` says to run
|
|
192
|
+
`nylorun studio`, which signs a browser in the same way; `nylorun studio
|
|
193
|
+
--no-open` prints the login URL (it works once, for two minutes) instead.
|
|
194
|
+
|
|
195
|
+
Each Tenant's Studio sets its own session cookie, `nylorun_studio_<name>`
|
|
196
|
+
(`NYLORUN_STUDIO_SESSION_COOKIE`).
|
|
197
|
+
|
|
198
|
+
### The Studio proxy
|
|
199
|
+
|
|
200
|
+
One small Caddy container per machine (`nylorun-proxy`, Compose project
|
|
201
|
+
`nylorun-proxy`, label `dev.nylorun.proxy: "true"`) gives every Tenant's Studio
|
|
202
|
+
the address `http://<name>.localhost:<port>`. Browsers keep cookies per host,
|
|
203
|
+
not per port, so separate hosts keep the Studios' sessions apart. The proxy is
|
|
204
|
+
for browsers only: programs keep using the Runtime's `http://localhost:<port>`.
|
|
205
|
+
It holds no Tenant data; its files are in `~/.nylorun/proxy/` (`compose.yaml`,
|
|
206
|
+
`Caddyfile`, and `.env` with `NYLORUN_PROXY_PORT`, 4160 or a free port chosen
|
|
207
|
+
on its first start and kept; Caddy's own state is tmpfs). Its image is pinned
|
|
208
|
+
by this release (`caddy:2.11.6`).
|
|
209
|
+
|
|
210
|
+
- Caddy listens on port 80 in the container, published at `NYLORUN_PROXY_PORT`
|
|
211
|
+
on `127.0.0.1` and `[::1]` (macOS resolves `*.localhost` to `::1` only); when
|
|
212
|
+
Docker refuses `::1` (IPv6 off), it publishes on `127.0.0.1` alone and says
|
|
213
|
+
so once.
|
|
214
|
+
- It routes every Tenant under `~/.nylorun/tenants/`: it joins each Tenant's
|
|
215
|
+
network and reaches `<project>-studio:3000`, passing the browser's `Host`
|
|
216
|
+
through, which Studio checks. A stopped Tenant answers 502 naming
|
|
217
|
+
`nylorun start --tenant <name>`; an unknown host 404 naming `nylorun ls`.
|
|
218
|
+
- `start` rewrites its files, brings it up (only when Studio starts: not with
|
|
219
|
+
`--no-studio`), joins every Tenant's network and reloads Caddy; Studio learns
|
|
220
|
+
its proxy origin from `NYLORUN_STUDIO_PUBLIC_ORIGINS`, written to the
|
|
221
|
+
Tenant's `.env` on every start. A proxy that does not come up never fails
|
|
222
|
+
`start`: it warns once and prints Studio's own URL.
|
|
223
|
+
- `reset` and `delete` detach it from the Tenant's network first; `delete`
|
|
224
|
+
removes the Tenant's route. `stop --all` stops it.
|
|
225
|
+
- `NYLORUN_PROXY_DISABLED=1` turns it off: Studio is `http://localhost:<port>`.
|
|
226
|
+
A Tenant under `NYLORUN_HOME` or `NYLORUN_COMPOSE_PROJECT` (the repository's
|
|
227
|
+
smokes) does not use it either.
|
|
228
|
+
|
|
229
|
+
`nylorun doctor` reports it on a `proxy` row: running (on which loopbacks and
|
|
230
|
+
port), stopped, not created yet, or disabled.
|
|
137
231
|
|
|
138
232
|
### Embedding Studio in a desktop app
|
|
139
233
|
|
|
140
234
|
A desktop app such as Babai Desktop can show Studio inside its own window, in
|
|
141
235
|
an iframe loaded from Studio's URL (`studio.url` in `nylorun status --json`).
|
|
142
236
|
Only exact origins listed in `NYLORUN_STUDIO_FRAME_ANCESTORS` (in
|
|
143
|
-
`~/.nylorun/
|
|
237
|
+
`~/.nylorun/tenants/<name>/docker/.env`) may frame it. The default is Babai's
|
|
144
238
|
`nylorun://localhost http://nylorun.localhost`; `nylorun status` lists them
|
|
145
239
|
under `Embeds`. While building such an app, add its dev server once with
|
|
146
240
|
`nylorun start --studio-embed-origin http://localhost:1420`; the list is kept
|
|
147
241
|
across starts until `--studio-embed-origin-reset`. Wildcards are refused.
|
|
148
242
|
|
|
149
|
-
The app's backend mints a single-use login token for the
|
|
243
|
+
The app's backend mints a single-use login token for the Tenant with
|
|
150
244
|
`mintStudioLoginToken` from `@nylorun/admin` (it needs the admin key), and its
|
|
151
245
|
page passes the token to Studio by `postMessage`. The message contract is
|
|
152
246
|
`@nylorun/agents/studio-embed`.
|
|
153
247
|
|
|
248
|
+
### Telemetry
|
|
249
|
+
|
|
250
|
+
Studio reports anonymous page views to Google Analytics, so we can see which
|
|
251
|
+
parts of it are used. A page view carries the route's shape only: every Tenant,
|
|
252
|
+
agent and session id becomes `:id` (`/tenants/:id/agents/:id/sessions/:id`)
|
|
253
|
+
and the query is dropped. Nothing you send to agents, no names, keys or
|
|
254
|
+
responses, and no Google signals or ad personalization are collected. Studio
|
|
255
|
+
loads no analytics inside an embedding app, or when the browser sends Do Not
|
|
256
|
+
Track or Global Privacy Control.
|
|
257
|
+
|
|
258
|
+
It is on by default, and `nylorun start` says so the first time. Turn it off on
|
|
259
|
+
this machine with `nylorun telemetry disable` (kept in
|
|
260
|
+
`~/.nylorun/telemetry.json`), or for one start with `NYLORUN_TELEMETRY_DISABLED=1`
|
|
261
|
+
or `DO_NOT_TRACK=1`. It is always off when `CI` is set. `nylorun start` decides
|
|
262
|
+
on every start and writes the result to `NYLORUN_STUDIO_ANALYTICS_ID` in
|
|
263
|
+
`docker/.env` (empty when off); `nylorun telemetry` reports the current choice.
|
|
264
|
+
|
|
154
265
|
## Sandboxes
|
|
155
266
|
|
|
156
267
|
A session gets a sandbox when it is opened with one, or when the Tenant's
|
|
157
|
-
default names one (`PUT /v1/tenant/sandbox`).
|
|
268
|
+
default names one (`PUT /v1/tenant/sandbox`). A local Tenant runs them on the
|
|
158
269
|
Runtime's **virtual** backend: an emulated shell in the Runtime process, with no
|
|
159
270
|
extra containers. It is not a VM or container boundary.
|
|
160
271
|
|
|
161
272
|
## Host root
|
|
162
273
|
|
|
163
|
-
The **Host root** is `~/.nylorun/
|
|
164
|
-
bind-mounted into the Runtime and Studio containers, and holds `
|
|
165
|
-
(the
|
|
166
|
-
|
|
167
|
-
0600), the Docker Compose files in
|
|
168
|
-
`
|
|
169
|
-
mounts. The Tenant's data lives in
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
volumes and Host root: the vault key (KEK) and all the Tenant's data go with it.
|
|
176
|
-
|
|
177
|
-
## Upgrading from a shared stack
|
|
178
|
-
|
|
179
|
-
Older releases ran one stack per machine (Compose project `nylorun`, Host root
|
|
180
|
-
`~/.nylorun`) with a Tenant per project. This release starts fresh and leaves
|
|
181
|
-
that stack as it is: `nylorun start` mentions it once, and `nylorun ls` shows
|
|
182
|
-
it. `nylorun legacy stop` stops it; `nylorun legacy delete --yes` removes its
|
|
183
|
-
containers, volumes and files under `~/.nylorun` (never `~/.nylorun/stacks`).
|
|
184
|
-
Model credentials come from each project's `.env` (or Studio), and agents
|
|
185
|
-
register again (`npm run dev`). See [MIGRATION.md](../MIGRATION.md).
|
|
274
|
+
The **Host root** is `~/.nylorun/tenants/<name>/`, or `NYLORUN_HOME`. It is
|
|
275
|
+
bind-mounted into the Runtime and Studio containers, and holds `tenant.json`
|
|
276
|
+
(`{ "format": 1, "name", "project"? }`: the Tenant's name and the project it
|
|
277
|
+
was created for), `host.json` (the client-facing host and port),
|
|
278
|
+
`host-credentials.json` (the admin key, mode 0600), the Docker Compose files in
|
|
279
|
+
`docker/`, the Tenant directory `tenant/` (homes, logs) and `keys/vault-kek`,
|
|
280
|
+
the Tenant's vault key, which only the gateway container mounts. The Tenant's data lives in its Postgres, Restate and S2 volumes.
|
|
281
|
+
|
|
282
|
+
`nylorun reset` deletes the selected Tenant's volumes, `tenant/` and `keys/`, and keeps
|
|
283
|
+
its files and ports; the next start creates the Tenant anew (with a new id) and
|
|
284
|
+
relinks the project. `nylorun delete <tenant> --yes` removes the Tenant's
|
|
285
|
+
containers, volumes and Host root: the vault key (KEK) and all its data go with it.
|
|
186
286
|
|
|
187
287
|
## Exit codes
|
|
188
288
|
|
|
@@ -190,11 +290,11 @@ register again (`npm run dev`). See [MIGRATION.md](../MIGRATION.md).
|
|
|
190
290
|
| --- | --- |
|
|
191
291
|
| 0 | Success |
|
|
192
292
|
| 1 | Generic failure, including a missing Docker or Compose v2 |
|
|
193
|
-
| 2 | Usage error (including no
|
|
194
|
-
| 3 | `status`: the Runtime is not answering; `stop`/`logs`: no
|
|
293
|
+
| 2 | Usage error (including no Tenant selected, or `delete` without `--yes`), or a removed or moved command |
|
|
294
|
+
| 3 | `status`: the Runtime is not answering; `stop`/`logs`: no Tenant yet; `delete`: no such Tenant; `start`: a Tenant created by nylorun 0.5 (reset it) |
|
|
195
295
|
| 4 | The Runtime port is held by another Host |
|
|
196
|
-
| 5 | `up`/`start`/`studio`: this nylorun pins a Runtime older than the one that last ran the
|
|
197
|
-
| 7 | The
|
|
296
|
+
| 5 | `up`/`start`/`studio`: this nylorun pins a Runtime older than the one that last ran the Tenant; update nylorun, or `start --allow-downgrade` |
|
|
297
|
+
| 7 | The containers, the Tenant or Studio did not become ready (an unavailable Tenant's cause is printed) |
|
|
198
298
|
| 130 / 143 | SIGINT / SIGTERM |
|
|
199
299
|
|
|
200
300
|
## Troubleshooting
|
|
@@ -204,9 +304,11 @@ register again (`npm run dev`). See [MIGRATION.md](../MIGRATION.md).
|
|
|
204
304
|
| Docker missing or not running | Install or start Docker Desktop, OrbStack or Colima; `nylorun doctor` checks |
|
|
205
305
|
| `426` from the Runtime | Upgrade nylorun (`npx nylorun@latest start`), or pin a matching older set |
|
|
206
306
|
| `Refusing to start Runtime …` (exit 5) | Upgrade nylorun (`npx nylorun@latest start`); `--allow-downgrade` only when both Runtimes share the database schema |
|
|
207
|
-
| `
|
|
208
|
-
| Port conflict | Change `NYLORUN_PORT` / `NYLORUN_STUDIO_PORT` in `~/.nylorun/
|
|
307
|
+
| `Tenant … is unavailable` (exit 7) | Follow the repair it names; `nylorun logs runtime` |
|
|
308
|
+
| Port conflict | Change `NYLORUN_PORT` / `NYLORUN_STUDIO_PORT` in `~/.nylorun/tenants/<name>/docker/.env` |
|
|
209
309
|
| Logs | `nylorun logs runtime -f` |
|
|
210
310
|
| Studio login expired | `nylorun studio` |
|
|
311
|
+
| `http://<name>.localhost:<port>` does not answer | `nylorun doctor` (the `proxy` row); `nylorun start` brings the proxy up; Studio's own port is in `nylorun status` |
|
|
312
|
+
| `Tenant … was created by nylorun 0.5` (exit 3) | `nylorun reset --tenant <name>` (its data starts fresh) |
|
|
211
313
|
|
|
212
314
|
See [MIGRATION.md](../MIGRATION.md).
|
package/dist/cli.js
CHANGED
|
@@ -3,28 +3,30 @@ import "./baseline.js";
|
|
|
3
3
|
import { baselineEnv } from "./baseline.js";
|
|
4
4
|
import { CliError } from "./errors.js";
|
|
5
5
|
import { isStackCommand, stackCommand, stackUsage, studioCommand, } from "./stack/index.js";
|
|
6
|
-
const usage = `nylorun <up|down|start|stop|status|logs|studio|reset|ls|delete|
|
|
6
|
+
const usage = `nylorun <up|down|start|stop|status|logs|studio|reset|ls|delete|doctor|telemetry>
|
|
7
7
|
|
|
8
|
-
Local
|
|
8
|
+
Local Tenants (Docker Compose), one per project:
|
|
9
9
|
${stackUsage}
|
|
10
|
-
doctor [--json] check Node, Docker and Compose v2, and the
|
|
10
|
+
doctor [--json] check Node, Docker and Compose v2, and the Tenant's health
|
|
11
|
+
telemetry [status|enable|disable] Studio's anonymous usage analytics (on unless disabled,
|
|
12
|
+
NYLORUN_TELEMETRY_DISABLED=1, DO_NOT_TRACK=1 or CI)
|
|
11
13
|
|
|
12
|
-
A command acts on the
|
|
13
|
-
NYLORUN_HOME sets its Host root
|
|
14
|
+
A command acts on the Tenant --tenant or NYLORUN_TENANT names, else the linked project's,
|
|
15
|
+
else (outside a project) the default Tenant; NYLORUN_HOME sets its Host root
|
|
16
|
+
(default ~/.nylorun/tenants/<name>).
|
|
14
17
|
|
|
15
|
-
nylorun sets up and runs local
|
|
16
|
-
project's
|
|
17
|
-
providers belong to the Runtime client: npx @nylorun/cli --help`;
|
|
18
|
+
nylorun sets up and runs local Tenants. "nylorun start" in a project creates the
|
|
19
|
+
project's Tenant and the Project link; anywhere else, it starts the default Tenant.
|
|
20
|
+
Agents, sessions and model providers belong to the Runtime client: npx @nylorun/cli --help`;
|
|
18
21
|
const CLIENT = "npx @nylorun/cli";
|
|
19
22
|
/** Commands that were removed, or moved to the Runtime client (`@nylorun/cli`, command `nylo`). */
|
|
20
23
|
const MOVED_TO_CLIENT = {
|
|
21
|
-
dev: "nylorun dev was removed: run `npx nylorun start` in your project (it creates the project's
|
|
22
|
-
tenant: `Tenant commands were removed: a stack serves one Tenant, which \`npx nylorun start\` in a project creates with the stack and the Project link. Use nylorun status|reset, or ${CLIENT} status|reset|endpoints.`,
|
|
24
|
+
dev: "nylorun dev was removed: run `npx nylorun start` in your project (it creates the project's Tenant and the Project link), then your project's `npm run dev`.",
|
|
23
25
|
configure: `nylorun configure moved to the Runtime client: ${CLIENT} configure`,
|
|
24
26
|
serve: "nylorun serve was removed. Use node dist/src/main.js with NYLORUN_RUNTIME_URL and NYLORUN_SERVER_KEY.",
|
|
25
|
-
runtime: "nylorun runtime was removed: the local Runtime runs in
|
|
27
|
+
runtime: "nylorun runtime was removed: the local Runtime runs in Docker Compose. Use nylorun up|down|status|logs.",
|
|
26
28
|
};
|
|
27
|
-
const LOCAL_UI_REMOVED = "--local-ui was removed: Studio runs in
|
|
29
|
+
const LOCAL_UI_REMOVED = "--local-ui was removed: Studio runs in its own container. Run nylorun studio.";
|
|
28
30
|
const usageError = (message) => new CliError(message, 2);
|
|
29
31
|
async function main() {
|
|
30
32
|
const [command, ...args] = process.argv.slice(2);
|
|
@@ -47,23 +49,23 @@ async function main() {
|
|
|
47
49
|
process.exitCode = await stackCommand(command, args, baselineEnv());
|
|
48
50
|
return;
|
|
49
51
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
52
|
+
if (command === "telemetry") {
|
|
53
|
+
const { telemetryCommand } = await import("./telemetry.js");
|
|
54
|
+
const { defaultNylorunRoot } = await import("./stack/stacks.js");
|
|
55
|
+
process.exitCode = await telemetryCommand(args, {
|
|
56
|
+
nylorunRoot: defaultNylorunRoot(),
|
|
57
|
+
env: baselineEnv(),
|
|
58
|
+
out: (line) => console.log(line),
|
|
59
|
+
});
|
|
56
60
|
return;
|
|
57
61
|
}
|
|
58
62
|
if (command === "doctor") {
|
|
59
|
-
// `doctor stack` and `doctor runtime` are older spellings of `doctor`.
|
|
60
|
-
const options = args[0] === "stack" || args[0] === "runtime" ? args.slice(1) : args;
|
|
61
63
|
if (args[0] === "sandbox")
|
|
62
64
|
throw usageError(`nylorun doctor sandbox moved to the Runtime client: ${CLIENT} doctor sandbox`);
|
|
63
|
-
if (
|
|
65
|
+
if (args.some((option) => option !== "--json"))
|
|
64
66
|
throw usageError("Usage: nylorun doctor [--json]");
|
|
65
67
|
const { doctorStack } = await import("./doctor.js");
|
|
66
|
-
process.exitCode = await doctorStack({ json:
|
|
68
|
+
process.exitCode = await doctorStack({ json: args.includes("--json"), env: baselineEnv() });
|
|
67
69
|
return;
|
|
68
70
|
}
|
|
69
71
|
throw usageError(usage);
|
package/dist/doctor.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Check, type StackDeps, type StackStatus } from "./stack/index.js";
|
|
1
|
+
import { type Check, type ProxyStatus, type StackDeps, type StackStatus } from "./stack/index.js";
|
|
2
2
|
export interface StackDoctorReport {
|
|
3
3
|
node: {
|
|
4
4
|
version: string;
|
|
@@ -6,20 +6,22 @@ export interface StackDoctorReport {
|
|
|
6
6
|
};
|
|
7
7
|
docker: Check;
|
|
8
8
|
compose?: Check;
|
|
9
|
-
|
|
10
|
-
/** Why no
|
|
11
|
-
|
|
9
|
+
tenant?: Pick<StackStatus, "name" | "project" | "home" | "state" | "runtime" | "tenant" | "studio" | "gateway">;
|
|
10
|
+
/** Why no Tenant was checked: none is selected here (a project without a link). */
|
|
11
|
+
noTenant?: string;
|
|
12
|
+
/** The machine's Studio proxy (`http://<tenant>.localhost:<port>`); never a failure. */
|
|
13
|
+
proxy?: ProxyStatus;
|
|
12
14
|
}
|
|
13
15
|
/**
|
|
14
|
-
* `nylorun doctor`: check the prerequisites of
|
|
15
|
-
* Docker, Compose v2) and, when they pass, the
|
|
16
|
+
* `nylorun doctor`: check the prerequisites of a local Tenant (Node 24+,
|
|
17
|
+
* Docker, Compose v2) and, when they pass, the Tenant's health. Prints the fix
|
|
16
18
|
* for each problem and returns 1 when a prerequisite is missing or a running
|
|
17
|
-
*
|
|
19
|
+
* Tenant is unhealthy; installs and starts nothing.
|
|
18
20
|
*/
|
|
19
21
|
export declare function doctorStack(options: {
|
|
20
22
|
json: boolean;
|
|
21
23
|
env?: Readonly<Record<string, string | undefined>>;
|
|
22
|
-
/**
|
|
24
|
+
/** Command dependencies (tests). */
|
|
23
25
|
deps?: StackDeps;
|
|
24
26
|
log?: (line: string) => void;
|
|
25
27
|
}): Promise<number>;
|