nylorun 0.16.0-beta → 0.18.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.
Files changed (44) hide show
  1. package/CHANGELOG.md +70 -0
  2. package/README.md +118 -70
  3. package/dist/cli.js +39 -14
  4. package/dist/client/agent-manifests.d.ts +4 -0
  5. package/dist/client/agent-manifests.js +100 -0
  6. package/dist/client/agents.d.ts +2 -4
  7. package/dist/client/agents.js +467 -117
  8. package/dist/client/apply.d.ts +7 -0
  9. package/dist/client/apply.js +99 -0
  10. package/dist/client/artifacts.js +3 -3
  11. package/dist/client/doctor.d.ts +1 -1
  12. package/dist/client/doctor.js +2 -2
  13. package/dist/client/io.d.ts +2 -0
  14. package/dist/client/io.js +11 -0
  15. package/dist/client/mcp.d.ts +5 -3
  16. package/dist/client/mcp.js +30 -23
  17. package/dist/client/migrate.d.ts +4 -0
  18. package/dist/client/migrate.js +140 -0
  19. package/dist/client/model/pi-ai.d.ts +1 -1
  20. package/dist/client/model/pi-ai.js +1 -1
  21. package/dist/client/models.d.ts +5 -2
  22. package/dist/client/models.js +17 -7
  23. package/dist/client/runtime.d.ts +1 -1
  24. package/dist/client/runtime.js +8 -6
  25. package/dist/client/sessions.js +30 -19
  26. package/dist/client/settings.d.ts +4 -4
  27. package/dist/client/settings.js +21 -20
  28. package/dist/client/signing-keys.js +3 -1
  29. package/dist/client/tenant.d.ts +1 -1
  30. package/dist/client/tenant.js +12 -7
  31. package/dist/command.d.ts +1 -1
  32. package/dist/command.js +6 -2
  33. package/dist/errors.d.ts +6 -0
  34. package/dist/errors.js +9 -0
  35. package/dist/nylo.js +4 -4
  36. package/dist/stack/commands.d.ts +11 -0
  37. package/dist/stack/commands.js +24 -1
  38. package/dist/stack/compose-file.js +5 -3
  39. package/dist/telemetry.js +3 -1
  40. package/package.json +9 -9
  41. package/dist/client/environment-manifests.d.ts +0 -10
  42. package/dist/client/environment-manifests.js +0 -173
  43. package/dist/client/environments.d.ts +0 -4
  44. package/dist/client/environments.js +0 -295
package/CHANGELOG.md CHANGED
@@ -1,5 +1,75 @@
1
1
  # nylorun
2
2
 
3
+ ## 0.18.0-beta
4
+
5
+ ### Minor Changes
6
+
7
+ - eeb6294: Session usage as one ledger (protocol 18). The usage ledger keeps each model call's cost by token kind (uncached input, cache read, cache write, output) at the prices the adapter applied (migration 0037). For a protocol 18 client, `GET /v1/sessions/{id}/calls/model` returns each call's `startedAt`, `endedAt` and `usage.costSplit` (null for a call recorded before), and `GET /v1/sessions/{id}/usage` adds `costSplit` with `splitCalls`, and the calls' durations added up as `modelTimeMs` with `timedCalls`. A protocol 16 or 17 client reads usage as before. Studio's Usage tab is rebuilt on them: a Session card with one tokens bar and a ledger of tokens and cost by kind adding up to a total row, then the model calls grouped by turn with the same columns (cached, uncached, output, total, time, cost), and a row menu whose View event opens the call's event in the Events tab.
8
+
9
+ ### Patch Changes
10
+
11
+ - ed08ba8: Public text names no internal roadmap codes: the OpenAPI documents' descriptions, the type comments of `@nylorun/core`, `@nylorun/agents` and `@nylorun/admin`, and the CLI's help, README and generated compose file. A Runtime test fails when either OpenAPI document names one.
12
+ - ed08ba8: `nylo` and the deprecated `@nylorun/cli` name the release that removes them, nylorun 0.19, where they said "one release": `nylo`'s message ends "nylorun 0.19 removes nylo.", and `@nylorun/cli`'s stderr line, description and README say nylorun 0.19 removes both.
13
+ - ed08ba8: `--help` (or `-h`) works on every command and subcommand: it prints that command's own usage on stdout and exits 0, where `nylorun migrate v8 --help`, `nylorun tenant budgets --help` and others exited 2 with "Unknown option --help", and `nylorun tenant settings --help` printed the usage of `budgets`, `tool-policy` and `coverage` too. `nylorun --help` lists every `agents` command (`pin`, `track`, `restart`, `triggers`, `runs` and `memories` were missing) and `migrate v8 --name`, and the README lists `agents pin`, `track`, `restart`, `put --dry-run`, `fork --label` and `list --outdated`.
14
+ - ed08ba8: Webhook URLs name the Runtime's public URL. A trigger's `webhookUrl` is at `NYLORUN_PUBLIC_URL`, else the origin the request reached, so behind a reverse proxy that rewrites `Host` to `localhost:<port>` it is the proxy's URL, not `http://localhost:<port>`; the Runtime API's `401` challenges name it too. `nylorun start` passes `NYLORUN_PUBLIC_URL` from its shell to the runtime container (default `http://localhost:<port>`).
15
+ - Pin core to the tested release.
16
+ - Pin agents to the tested release.
17
+ - Pin admin to the tested release.
18
+ - Pin runtime to the tested release.
19
+ - Pin studio to the tested release.
20
+ - Updated dependencies [ed08ba8]
21
+ - Updated dependencies [ed08ba8]
22
+ - Updated dependencies [ed08ba8]
23
+ - Updated dependencies [ed08ba8]
24
+ - Updated dependencies [eeb6294]
25
+ - Updated dependencies [ed08ba8]
26
+ - Updated dependencies
27
+ - Updated dependencies
28
+ - @nylorun/core@0.25.0-beta
29
+ - @nylorun/agents@0.25.0-beta
30
+ - @nylorun/admin@0.19.1-beta
31
+
32
+ ## 0.17.0-beta
33
+
34
+ ### Minor Changes
35
+
36
+ - cc8d034: Track T3 in the clients. The SDK has `client.agents.plan(id, input)` (what a move would do), `client.agents.restart(id, { retry? })` and `list({ outdated: true })`. The CLI has `nylorun agents pin <id> <n>`, `track <id>`, `restart <id> [--retry]`, `put --dry-run`, and `list --outdated` (`--behind` kept as its alias), and prints the version an Agent moves to. Studio's Agent page moves an Agent (Move to vN, Pin, Track), restarts it on a pending version or retries a failed one, and shows "vN at next start", a version waiting for secrets, or one that failed to start. The starter's dev loop no longer deletes and remakes its Agent: the tracking Agent moves on each save.
37
+ - 22c61ce: Protocol 16, Agents from one manifest (track T2), a fresh start. An agent manifest (v8) is one versioned document at `/v1/agent-manifests/{name}` with a `harness` section (what runs inside the loop, including the harness's id) and a `runtime` section (what an environment manifest said). The Runtime checks the two against each other when it is saved (`422 manifest_inconsistent` with `details.gaps`), in place of `requires` at session open. Agent definitions and environment manifests are gone.
38
+
39
+ Environments are Agents: `/v1/agents/{id}` and its sub-routes, made from a saved manifest only (`manifest: "name"` tracks it, `"name@n"` pins a version; either resolves once, into `resolvedVersion`), with a derived `state` (`working`, `sleeping`, `input_required`, `failing`, `paused`) and `attention`. Every session runs on one Agent (`PUT /v1/sessions/{id} { agent, ownerUserId }`) and pins its manifest version. No session is special (D71). Error codes, events (`agent.*`), scopes (`agents:write`, `agent-manifests:write`) and identity-file grants (`agents`) say Agent; model budget scope `agent` is `manifest`. Harness API 5: `turn.start.agent` replaces `turn.start.environment`, with `definition` and `loop`. Migration 0032 closes older sessions (`protocol_16`) and drops Environments with their disks and vaults.
40
+
41
+ The SDK has `client.agentManifests`, `client.agents` and `composeManifest(dir)` for three-file authoring; the CLI has `nylorun apply`, `nylorun agent-manifests`, `nylorun agents` and `nylorun migrate v8`; Studio has an Agents screen, an Agent page and an Agent manifests screen. See MIGRATION.md.
42
+
43
+ - 4fa160d: Agent memory, storage and API (track T5, D72). An agent manifest's `harness.memory` (`access`: `read_write` or `read_only`; `instructions`, at most 4,096 characters) turns on the Agent's memory: Markdown files under `/memories` it keeps across sessions, wakes and upgrades. The Runtime keeps them in Postgres (`memories`, `memory_versions`, migration 0036) with a version per change and who made it. `GET /v1/agents/{id}/memories` lists them (`pathPrefix`), `GET`, `PUT` (whole content, with an optional `contentSha256` precondition: `409 memory_conflict`) and `DELETE /v1/agents/{id}/memories/{path}` read, write and delete one (or a folder), and `GET /v1/agents/{id}/memory_versions` and `.../memory_versions/{versionId}` page the versions. A fork copies the memories (the fork plan adds `memories`); a delete removes them. `@nylorun/core` adds `memoryPathOf`, `memoryDescriptionOf` and the memory contracts; new Runtime limits `memoryBytes` (100 KiB) and `memoriesPerAgent` (10,000); new error code `memory_conflict`. The SDK adds `client.agents.memories`; the CLI adds `nylorun agents memories ls|cat|put|rm|versions`. The model's `memory` tool arrives in the next steps of T5.
44
+ - 9e60e40: Protocol 17, a queue per session (track T4, D76). A message sent while the session's turn runs or waits is queued (`{status: "queued", queuedMessageId, position}`, `message.queued`) and starts the next turn when this one ends, with every queued message, each its own user message (`queue.taken`); a cancel ends the turn, not the queue. `delivery: "reject"` keeps the refusal, now `409 session_busy`, and a protocol 16 client's messages default to it, so the Host serves protocol 16 and 17. The queue holds at most the Runtime limit `sessionQueuedMessages` (`429 queue_full`), and session reads count `queuedMessages`. Our engine takes `{kind: "messages", messages}` as a turn's input. The SDK's `input` and `inputParts` take `delivery`, and the CLI's `sessions send` takes `--reject-if-busy`. See MIGRATION.md.
45
+ - f85483d: Triggers (track T4, D74). An agent manifest's `runtime.triggers` declares `schedule` (cron with an IANA `timezone`) and `at` triggers, each with the session its runs go to (a session id, opened on the first run, or `new` for a session per run) and its prompt. They start active with a new Agent, fire on a durable timer per trigger with Postgres as the truth (one late fire after downtime, never a backfill, a fixed jitter per trigger), and each fire is a run (`started`, `queued`, `skipped` or `failed`, with a reason) at `GET /v1/agents/{id}/runs`. A schedule adds at most one queued message to a busy session. `GET /v1/agents/{id}/triggers` and `POST .../triggers/{triggerId}/pause`, `/resume` and `/run` (with an `Idempotency-Key`); Agent reads add `nextWakeAt`, and the Agent's stream adds `agent.run`, `agent.trigger_paused` and `agent.trigger_resumed`. New Runtime limits: `triggersPerAgent`, `triggerMinIntervalMs` and `triggerRunRetentionMs` (with floors), `triggerRunsPerHour`, `triggerJitterPercent`, `triggerJitterMaxMs`, `triggerPromptChars`; Host tuning `triggers.lateGraceMs` and `triggers.intervalCheckFires`. The SDK's `client.agents` adds `triggers`, `pauseTrigger`, `resumeTrigger`, `runTrigger` and `runs`; the CLI adds `nylorun agents triggers` and `nylorun agents runs`.
46
+ - ae54de7: Webhook triggers (track T4, D75). A `webhook: "standard-webhooks"` trigger has an endpoint, `POST /v1/webhooks/{endpointId}`, an anonymous, unversioned route that takes any body up to the new Runtime limit `webhookBodyBytes` and verifies Standard Webhooks (`webhook-id`, `webhook-timestamp` within the Host's `triggers.webhookToleranceMs`, `webhook-signature`) in the keys service, which alone opens the trigger's sealed secret; anything else is `401` and writes nothing. A delivery runs the trigger once per `webhook-id` (`202 {runId, status}`); a paused trigger answers a signed one `409 trigger_paused`. `POST /v1/agents/{id}/triggers/{triggerId}/secret` makes or replaces the `whsec_` secret, shown once (`agent.trigger_secret_rotated`); trigger reads show `webhookUrl` and `secretSet`. The payload reaches the model under the trigger's prompt in a labelled `<trigger-payload>` block. The SDK adds `agents.rotateWebhookSecret`, and the CLI `nylorun agents triggers new-secret`.
47
+
48
+ ### Patch Changes
49
+
50
+ - Pin core to the tested release.
51
+ - Pin agents to the tested release.
52
+ - Pin admin to the tested release.
53
+ - Pin runtime to the tested release.
54
+ - Pin studio to the tested release.
55
+ - Updated dependencies [218b078]
56
+ - Updated dependencies [cc8d034]
57
+ - Updated dependencies [22c61ce]
58
+ - Updated dependencies [1ded443]
59
+ - Updated dependencies [76dcd11]
60
+ - Updated dependencies [bf942ed]
61
+ - Updated dependencies [4fa160d]
62
+ - Updated dependencies [9fed948]
63
+ - Updated dependencies [ffeb3bb]
64
+ - Updated dependencies [9e60e40]
65
+ - Updated dependencies [f85483d]
66
+ - Updated dependencies [ae54de7]
67
+ - Updated dependencies
68
+ - Updated dependencies
69
+ - @nylorun/core@0.24.0-beta
70
+ - @nylorun/agents@0.24.0-beta
71
+ - @nylorun/admin@0.19.0-beta
72
+
3
73
  ## 0.16.0-beta
4
74
 
5
75
  ### Minor Changes
package/README.md CHANGED
@@ -15,7 +15,7 @@ and S2, serving exactly that Tenant, and its name is the Tenant's name.
15
15
  `nylorun start` in a project creates the project's Tenant (the Runtime creates
16
16
  it on its first start) and links the project to it; anywhere else, it starts
17
17
  the Tenant `default`. Projects that must not share agents, credentials or
18
- history run separate Tenants. The `tenant` and `environments` groups act on a
18
+ history run separate Tenants. The `tenant`, `agents` and `apply` commands act on a
19
19
  Tenant over its APIs, so they work on a remote installation too
20
20
  ([below](#remote-installations)). Depends on `@nylorun/core`,
21
21
  `@nylorun/admin` and `@nylorun/agents` among Nylorun packages and never imports
@@ -38,7 +38,8 @@ npx nylorun doctor # Node 24+, Docker, Compose v2, and the Tenan
38
38
  ## Commands
39
39
 
40
40
  The installation's lifecycle is a handful of top-level commands; everything else
41
- is in a group that follows the API it uses, and each group has its own `--help`.
41
+ is in a group that follows the API it uses. Every group and command takes `--help`
42
+ (or `-h`), which prints its own usage and exits 0.
42
43
 
43
44
  ```sh
44
45
  nylorun up|start [--tenant <name>] [--no-link] [--no-studio] [--allow-downgrade] [--studio-embed-origin <origin>]... [--studio-embed-origin-reset] [--restate-ui]
@@ -50,32 +51,36 @@ nylorun studio [--tenant <name>] [--no-open] # sign a browser in to Studio on
50
51
  nylorun doctor [--json] # prerequisites and the Tenant's health
51
52
  nylorun doctor sandbox [--tenant <name>] [--json] # the sandbox backend the Tenant's Host offers
52
53
 
53
- # agents, sessions, environments, artifacts: the Runtime API (an application key, or NYLORUN_TOKEN)
54
+ # apply, agent-manifests, agents, sessions, artifacts: the Runtime API (an application key, or NYLORUN_TOKEN)
54
55
  # every one takes --tenant <name>, and --as <subject> [--scope <scope>]... to act for a person
55
- nylorun agents list [--json]
56
- nylorun agents get <id> # its manifest
57
- nylorun agents save <manifest.json|-> [--files <dir>]... [--implementation-version <v>] [--dry-run]
58
- nylorun sessions list [--agent <id>] [--status <s>] [--environment <id>] [--owner <user>] [--limit <n>] [--cursor <c>] [--json]
59
- nylorun sessions create --agent <id> --owner <user> [--environment <id>] [--id <id>] [--info <json>]
56
+ nylorun apply [<dir>...] [--dry-run] [--if-match <n>] # plan, then save each folder's agent.manifest.json, its files uploaded
57
+ nylorun migrate v8 <agent.json> [--runtime <environment-manifest.json>] [--name <name>] [--out <dir>] # the three files from a v7 manifest; reads no Runtime
58
+ nylorun agent-manifests list [--json] # name, latest version, runtime kind, harness, Agents
59
+ nylorun agent-manifests get <name>[@<n>] | versions <name> | rm <name>
60
+ nylorun agents list [--state <s>] [--manifest <name>] [--label <key=value>]... [--outdated] [--limit <n>] [--cursor <c>] [--json] # --outdated (or --behind): moving to another manifest version
61
+ nylorun agents get|stop|reset|rm|snapshot|versions <id>
62
+ nylorun agents put <id> --manifest <name[@n]> [--owner <user>] [--label <key=value>]... [--dry-run] # name tracks its latest version, name@n pins one; --dry-run prints the move
63
+ nylorun agents pin <id> <version> # move it to that manifest version, and keep it there
64
+ nylorun agents track <id> # move it to its manifest's latest version, and with each save
65
+ nylorun agents restart <id> [--retry] # apply the version it waits to start on now; --retry: the one that failed to start
66
+ nylorun agents fork <id> <new-id> [--manifest <name[@n]>] [--disk <latest|n|empty>] [--secrets <copy|none>] [--label <key=value>]... [--dry-run] # onto a new manifest version
67
+ nylorun agents restore <id> <version|latest>
68
+ nylorun agents delete-version <id> <version>
69
+ nylorun agents events <id> [--from <n>] [--types <type,…>] [--since <time>] [--until <time>]
70
+ nylorun agents triggers list <id> | pause|resume <id> <trigger> | run <id> <trigger> [--idempotency-key <k>] | new-secret <id> <trigger>
71
+ nylorun agents runs <id> [--trigger <id>] [--limit <n>] [--cursor <c>] # what each trigger fire came to
72
+ nylorun agents memories ls|cat|put|rm|versions <id> [<path>] [<file|->] # its memories; put seeds one
73
+ nylorun agents secrets list|get|put|rm <id> [<name>] [<secret.json|->] # put without a file: a slot's value on stdin
74
+ nylorun sessions list [--agent <id>] [--manifest <name>] [--status <s>] [--owner <user>] [--limit <n>] [--cursor <c>] [--json]
75
+ nylorun sessions create --agent <id> --owner <user> [--id <id>] [--info <json>] # a session on Agent <id>
60
76
  nylorun sessions get <id>
61
- nylorun sessions send <id> [<text>] [--data <json>] [--file <artifact>[@<version>]]... [--idempotency-key <k>]
77
+ nylorun sessions send <id> [<text>] [--data <json>] [--file <artifact>[@<version>]]... [--idempotency-key <k>] [--reject-if-busy] # queued while a turn runs
62
78
  nylorun sessions approve <id> <interaction> [--deny]
63
79
  nylorun sessions respond <id> <interaction> <json>
64
80
  nylorun sessions cancel <id> [--reason <text>]
65
81
  nylorun sessions watch <id> [--follow] [--cursor <c>] # events as JSON lines until interrupted
66
82
  nylorun sessions history|usage|calls [--tool]|trace <id> …
67
83
  nylorun sessions exec <id> [--timeout <s>] -- <command>... # bash in the session's sandbox
68
- nylorun environments list [--label <key=value>]... [--behind] [--limit <n>] [--cursor <c>] [--json] # --behind: made from an older manifest version
69
- nylorun environments get|stop|reset|delete|snapshot|versions <id>
70
- nylorun environments put <id> --manifest <name[@n]> [--label <key=value>]... # made from a manifest version; what it runs never changes
71
- nylorun environments put <id> [<inline.json|->] [--kind <virtual|pod|none>] [--label <key=value>]...
72
- nylorun environments fork <id> <new-id> [--manifest <name[@n]>] [--disk <latest|n|empty>] [--secrets <copy|none>] [--dry-run] # onto a new manifest version
73
- nylorun environments restore <id> <version|latest>
74
- nylorun environments delete-version <id> <version>
75
- nylorun environments events <id> [--from <n>] [--types <type,…>] [--since <time>] [--until <time>]
76
- nylorun environments secrets list|get|put|rm <id> [<name>] [<secret.json|->] # put without a file: a slot's value on stdin
77
- nylorun environments manifests list [--json] | get <name> [--version <n>] | versions <name> | rm <name>
78
- nylorun environments manifests save <manifest.json>... [--if-match <n>] [--dry-run] # files with "from": a folder, uploaded by hash
79
84
  nylorun artifacts list [--session <id>] [--label <key=value>]... [--limit <n>] [--cursor <c>] [--json]
80
85
  nylorun artifacts get|tree|diff|link|rm <id> …
81
86
  nylorun artifacts upload <file|-> [--name <name>] [--content-type <type>] [--session <id>] [--label <key=value>]... [--to <id>]
@@ -83,7 +88,7 @@ nylorun artifacts download <id> [--version <n>] [--output <file>]
83
88
  nylorun artifacts zip <id> [--version <n>] --output <file>
84
89
 
85
90
  # tenant: the Tenant's settings (Management API, a management key)
86
- nylorun tenant reset [--sessions|--environments|--all] [--yes] [--tenant <name>]
91
+ nylorun tenant reset [--sessions|--agents|--all] [--yes] [--tenant <name>]
87
92
  nylorun tenant keys put <id> [--management] [--tenant <name>] # create or rotate key <id>; prints it once
88
93
  nylorun tenant keys list [--tenant <name>] [--json] # id, role, when issued
89
94
  nylorun tenant keys rm <id> [--tenant <name>] # it stops working at once
@@ -92,13 +97,13 @@ nylorun tenant models catalog|providers|get [--tenant <name>] [--json] # the m
92
97
  nylorun tenant models set [--tenant <name>] # sign in to a model provider and set the Tenant's model
93
98
  nylorun tenant models set --provider <id> --model <id> [--base-url <url>] [--tenant <name>] # the same, with an API key piped in on stdin (CI)
94
99
  nylorun tenant models select <provider> [--model <id>] [--tenant <name>] # use another provider that has a credential
95
- nylorun tenant usage [--scope tenant|agent|turn] [--id <id>] [--period day|month|total] [--tenant <name>] # calls, tokens and cost (JSON)
100
+ nylorun tenant usage [--scope tenant|manifest|turn] [--id <id>] [--period day|month|total] [--tenant <name>] # calls, tokens and cost (JSON); manifest: the Agents made from agent manifest <id>
96
101
  nylorun tenant calls [--after <cursor>] [--limit <n>] [--tenant <name>] # every recorded model call as NDJSON, until caught up
97
- nylorun tenant budgets [get | put <file|->] [--tenant <name>] # the model spend caps
102
+ nylorun tenant budgets [get | put <file|->] [--tenant <name>] # the model spend caps: tenant, manifest (id: its name) or turn
98
103
  nylorun tenant tool-policy [get | put <file|->] [--tenant <name>] # the Tool Gate's rules
99
- nylorun tenant settings sandbox|artifacts|skills|limits [get | put <file|->] [--tenant <name>] # Environment, artifact store and skill settings, Runtime limits
100
- nylorun tenant coverage --agent <id> [--environment <id>] [--tenant <name>] [--json] # which secret each MCP server and HTTP tool would get
101
- nylorun tenant mcp inspect <url> [--server <name>] [--environment <id>] [--sse] [--tenant <name>] [--json]
104
+ nylorun tenant settings sandbox|artifacts|skills|limits [get | put <file|->] [--tenant <name>] # Agents' environments, artifact store and skill settings, Runtime limits
105
+ nylorun tenant coverage --agent <id> [--tenant <name>] [--json] # which secret of Agent <id>'s vault each MCP server and HTTP tool would get
106
+ nylorun tenant mcp inspect <url> [--server <name>] [--agent <id>] [--sse] [--tenant <name>] [--json]
102
107
 
103
108
  # local: the Tenants on this machine (Docker and kubectl)
104
109
  nylorun local ls [--json] # the Tenants on this machine, with their state, memory and URLs
@@ -116,14 +121,17 @@ stops the containers and keeps the volumes, so no Tenant data is lost. A command
116
121
  that moved into a group, or was removed, exits 2 naming its replacement:
117
122
  `nylorun logs`, `ls`, `delete`, `reset` and `telemetry` are under `local` (and
118
123
  `sandbox enable|disable|status`); `nylorun key` and `mcp` are under `tenant`;
119
- `nylorun sandbox ls|rm` is `nylorun environments list|delete`; `nylorun
120
- configure` is `nylorun tenant models set`. `nylorun dev`, `nylorun env` and the
121
- MCP OAuth `connect` subcommand of `nylorun tenant mcp` (protocol 10: write a key
122
- or a gateway credential as an Environment's secret instead) are gone.
124
+ `nylorun sandbox ls|rm` is `nylorun agents list|rm`; `nylorun environments` is
125
+ `nylorun agents` (protocol 16: Environments are Agents, and environment manifests
126
+ are the runtime section of an agent manifest); `nylorun agents save` is `nylorun
127
+ apply`; `nylorun configure` is `nylorun tenant models set`. `nylorun dev`,
128
+ `nylorun env` and the MCP OAuth `connect` subcommand of `nylorun tenant mcp`
129
+ (protocol 10: write a key or a gateway credential as an Agent's secret instead)
130
+ are gone.
123
131
 
124
132
  The package's second command, `nylo`, was the Runtime client until nylorun took
125
- its commands. For one release it names the `nylorun` command that replaced each
126
- of its own and exits 2:
133
+ its commands. Until nylorun 0.19, which removes it, it names the `nylorun`
134
+ command that replaced each of its own and exits 2:
127
135
 
128
136
  | `nylo` | `nylorun` |
129
137
  | --- | --- |
@@ -260,19 +268,21 @@ shows each key's id, role and when it was issued, never the keys; `nylorun
260
268
  tenant keys rm <id>` deletes one. Ids match `^[a-z][a-z0-9-]{0,31}$`; `studio`
261
269
  belongs to Studio and `bootstrap` to `NYLORUN_MANAGEMENT_KEY_FILE`, and both are
262
270
  refused. Putting an id that holds the other role is refused. Give each app server
263
- its own application key. On a local Tenant, the `tenant` and `environments`
271
+ its own application key. On a local Tenant, the `tenant` and Runtime API
264
272
  commands use the linked project's keys, or the keys `cli` and `cli-management`
265
273
  they put once and keep in `<Host root>/cli-credentials.json` (mode 0600).
266
274
 
267
275
  ## MCP servers
268
276
 
269
- An agent names its MCP servers by URL; a session gets a credential for a URL from
270
- the Environment it is opened on (`createSession({ environment })`): a secret of that
271
- Environment, a `bearer` token or a `headers` map, with `via` and an identity
272
- header when an MCP gateway holds each person's sign-in. Write it with
273
- `nylorun environments secrets put <id> <name> <secret.json|->` (the secret's JSON
277
+ An agent manifest names its MCP servers by URL, and may name the runtime
278
+ section's secret slot each one authenticates with (`credential`); a session gets
279
+ a credential for a URL from the Agent it runs on (`createSession({ agent })`): a
280
+ secret of that Agent's vault, a `bearer` token or a `headers` map, with `via` and
281
+ an identity header when an MCP gateway holds each person's sign-in. Write it with
282
+ `nylorun agents secrets put <id> <name>` (a slot's value on standard input) or
283
+ `nylorun agents secrets put <id> <name> <secret.json|->` (the secret's JSON
274
284
  comes from a file or standard input, never the command line),
275
- `client.environments.secrets.put(id, name, secret)` of `@nylorun/agents` (the
285
+ `client.agents.secrets.put(id, name, secret)` of `@nylorun/agents` (the
276
286
  Runtime API, an application key) or in Studio.
277
287
  The whole flow, with gateway recipes, is in
278
288
  [DEPLOYMENT.md](../../guides/DEPLOYMENT.md#mcp-servers-and-http-tools).
@@ -280,7 +290,7 @@ The whole flow, with gateway recipes, is in
280
290
  `nylorun tenant mcp inspect <url>` shows what a remote MCP server offers before an
281
291
  agent names it, through the Tenant's Management API
282
292
  (`POST /v1/tenant/mcp/preview`, with the management key). The Runtime connects
283
- with Environment `<id>`'s credential for `<url>` when `--environment <id>` names one
293
+ with Agent `<id>`'s credential for `<url>` when `--agent <id>` names one
284
294
  (without it, no credential is sent), lists the tools within 15 s and calls none. It
285
295
  prints a table of each tool's model name, input schema size, hints
286
296
  (`read-only`, `destructive`, `idempotent`) and description, then the tools
@@ -288,7 +298,7 @@ renamed for the model. `--server` is the server name your manifest uses (default
288
298
  the host's name, `linear` for `mcp.linear.app`); `--sse` speaks the older SSE
289
299
  transport; `--json` prints the Runtime's answer. A server that answers `401`
290
300
  needs a credential: it says so, and names the server's sign-in from its
291
- protected-resource metadata, since such a server needs a key in an Environment's
301
+ protected-resource metadata, since such a server needs a key in an Agent's
292
302
  secrets or an MCP gateway that holds each person's sign-in. A server it cannot list exits 1 with
293
303
  the reason (`mcp.unreachable` for an address the Runtime refuses).
294
304
 
@@ -382,20 +392,22 @@ on every start and writes the result to `NYLORUN_STUDIO_ANALYTICS_ID` in
382
392
 
383
393
  ## Sandboxes
384
394
 
385
- A session gets a sandbox from the Environment it is opened on
386
- (`createSession({ environment: id })`; protocol 11): an Environment has its own id
387
- (`PUT /v1/environments/{id}`, `client.environments` in `@nylorun/agents`), one
388
- sandbox and one vault of secrets, and outlives the sessions that name it. A session
389
- opened on none has no sandbox. Kind `virtual` (the default) runs on the Runtime's
390
- **virtual** backend: an emulated shell in the Runtime process, with no extra
391
- containers. It is not a VM or container boundary. Kind `pod` runs in a pod on a
392
- cluster (below).
393
-
394
- `nylorun environments list` lists the Tenant's Environments with their kind,
395
- state, sessions and labels; `nylorun environments delete <id>` deletes one, with its files
396
- and vault (refused while a turn runs in it). Neither starts a stopped Tenant
397
- (exit 3). The Tenant's limits for Environments (`limits.environments`, `idle`,
398
- resources, network) are `PUT /v1/tenant/sandbox` on the Management API.
395
+ A session gets a sandbox from the Agent it runs on (`createSession({ agent: id })`;
396
+ protocol 16): an Agent has its own id (`PUT /v1/agents/{id}`, `client.agents` in
397
+ `@nylorun/agents`), is made from a saved agent manifest, has the sandbox its
398
+ manifest's `runtime.kind` gives and one vault of secrets, and outlives its
399
+ sessions. Kind `virtual` runs on the Runtime's **virtual** backend: an emulated
400
+ shell in the Runtime process, with no extra containers. It is not a VM or
401
+ container boundary. Kind `pod` runs in a pod on a cluster (below); kind `none`
402
+ has no sandbox, and a manifest with no runtime section makes Agents of kind
403
+ `none`.
404
+
405
+ `nylorun agents list` lists the Tenant's Agents with the manifest version each
406
+ runs, its kind, state, sessions, owner and labels; `nylorun agents rm <id>`
407
+ deletes one, with its files and vault (refused while a turn runs on it). Neither
408
+ starts a stopped Tenant (exit 3). The Tenant's limits for Agents
409
+ (`limits.environments`, `idle`, resources, network) are `PUT /v1/tenant/sandbox`
410
+ on the Management API.
399
411
 
400
412
  ### Pods on a cluster (preview)
401
413
 
@@ -411,7 +423,7 @@ service to the Tenant: the one container holding the cluster credentials
411
423
  (`<Host root>/sandboxes/`). On kind under Linux, pass `--host-address 172.17.0.1`.
412
424
  `nylorun local sandbox disable` removes the service (`--delete-namespace` also deletes
413
425
  the namespace and every sandbox in it). Sessions run in a pod when their
414
- Environment has kind `pod` (`client.environments.put(id, { kind: "pod" })`).
426
+ Agent's manifest has `runtime.kind` `pod`.
415
427
 
416
428
  ## Host root
417
429
 
@@ -431,14 +443,14 @@ containers, volumes and Host root: the vault key (KEK) and all its data go with
431
443
 
432
444
  ## Remote installations
433
445
 
434
- The `agents`, `sessions`, `environments`, `artifacts` and `tenant` groups,
446
+ The `apply`, `agent-manifests`, `agents`, `sessions`, `artifacts` and `tenant` commands,
435
447
  `status` and `doctor sandbox` act on a Tenant over its APIs. Without `--tenant`, they act on the installation the
436
448
  environment names, when it names one for their API:
437
449
 
438
450
  | Variables | Acts on |
439
451
  | --- | --- |
440
452
  | `NYLORUN_RUNTIME_URL` and `NYLORUN_MANAGEMENT_KEY` | `status`, `doctor sandbox` and `tenant` (the Management API) |
441
- | `NYLORUN_RUNTIME_URL` and `NYLORUN_SERVER_KEY` | `agents`, `sessions`, `environments` and `artifacts` (the Runtime API) |
453
+ | `NYLORUN_RUNTIME_URL` and `NYLORUN_SERVER_KEY` | `apply`, `agent-manifests`, `agents`, `sessions` and `artifacts` (the Runtime API) |
442
454
  | `NYLORUN_RUNTIME_URL` and `NYLORUN_TOKEN` | the same, with an identity provider's token in place of the key: the person it names, with the scopes it grants |
443
455
 
444
456
  `NYLORUN_RUNTIME_URL` alone is an app's and names nothing, as for
@@ -459,16 +471,52 @@ sessions and to the scopes given (`--scope`, repeatable; default
459
471
  `sessions:own`). Use it to see what one person sees, or to act on their sessions
460
472
  from a terminal.
461
473
 
462
- ### Saving an agent from its manifest
474
+ ### Agent manifests: `apply`
463
475
 
464
- `nylorun agents save agent.json --files skills/` saves the agent a manifest
465
- describes, as `saveAgent` does from code. A manifest names each definition file
466
- (a skill folder's files) by the SHA-256 of its bytes, so the files under the
467
- `--files` folders are matched by content, whatever their paths; the ones the
468
- Runtime does not hold are uploaded first (`PUT /v1/files/sha256:…`). A file the
469
- manifest names but no folder holds stops the save before any request, naming
470
- where the manifest names it. `nylorun agents get <id>` prints a saved agent's
471
- manifest; the Runtime does not hand files back, so keep them with the manifest.
476
+ An agent runs from a saved **agent manifest** (protocol 16): one named, versioned
477
+ document with a harness section (instructions, tools, skills, MCP servers,
478
+ plugins) and a runtime section (kind, image, network, setup, files, secret
479
+ slots). Author it as files, one folder per agent:
480
+
481
+ ```
482
+ agents/triage/agent.manifest.json # { "manifestSchemaVersion": 8, "name": "triage",
483
+ # "harness": "./harness.manifest.json",
484
+ # "runtime": "../../shared/runtime.manifest.json" }
485
+ agents/triage/harness.manifest.json # instructions, tools, "skills": "./skills",
486
+ # "mcpServers": "./mcp.json", "plugins": ["../../plugins/github"],
487
+ # "credentials": { "linear": "linear" }, "requires": { "sandbox": "any" }
488
+ agents/triage/skills/<skill>/SKILL.md
489
+ shared/runtime.manifest.json # kind, image, "files": [{ "path": "/workspace/kit", "from": "./kit" }], secrets
490
+ ```
491
+
492
+ `nylorun apply agents/triage` composes the folder as `composeManifest` of
493
+ `@nylorun/agents` does (each path relative to the file that names it; skills,
494
+ plugins and `from` folders hashed; `credentials` set on the servers and HTTP
495
+ tools it names; `requires` checked against the runtime and left out), prints the
496
+ plan (`triage: version 2 → 3`, then each change as `section path op`, warnings
497
+ and errors) and saves it under `If-Match` set to the version it planned
498
+ against, uploading the files the Runtime does not hold (`PUT /v1/files/sha256:…`).
499
+ A manifest whose sections do not fit, or whose runtime misses what its harness
500
+ `requires`, is an error: nothing is saved and the command exits 1. `--dry-run`
501
+ prints the plans only; `--if-match <n>` saves only over version `n`.
502
+ `nylorun apply agents/` applies every subfolder with an `agent.manifest.json`;
503
+ every folder composes before anything is sent.
504
+
505
+ `nylorun agent-manifests list` shows each manifest's latest version, runtime
506
+ kind, harness and the Agents made from it; `get <name>[@<n>]` prints a version,
507
+ `versions <name>` its history and `rm <name>` deletes it (refused while an Agent
508
+ was made from it). Make an Agent from it with `nylorun agents put <id> --manifest
509
+ <name>` (tracking its latest version) or `--manifest <name>@<n>` (pinned), and
510
+ open sessions on it with `nylorun sessions create --agent <id> --owner <user>`.
511
+
512
+ `nylorun migrate v8 agent.json [--runtime box.json] [--out agents/triage]`
513
+ writes the three files from an agent manifest v7 (as `nylorun agents save` took
514
+ it) and the environment manifest v1 its sessions ran in: the environment
515
+ manifest's fields become the runtime file, its `harness` the harness file's `id`,
516
+ and v7's `requires` stays in the harness file for `apply` to check. With no
517
+ environment manifest the kind is `pod` when the agent requires one, `virtual`
518
+ when it has skills or requires a sandbox, else `none`. It overwrites no file and
519
+ prints the gaps to fix before `apply`.
472
520
 
473
521
  ### `local reset` or `tenant reset`
474
522
 
@@ -477,7 +525,7 @@ Both reset a Tenant, in different ways:
477
525
  | | `nylorun local reset` | `nylorun tenant reset` |
478
526
  | --- | --- | --- |
479
527
  | Acts on | the local Tenant on this machine, through Docker | the Tenant, local or remote, through the Management API with a management key |
480
- | Deletes | all the Tenant's data: volumes, `tenant/` and the vault key; the next `start` creates it anew, with a new id, and relinks the project | the sessions (the default), the Environments (`--environments`) or all the data (`--all`) after draining work in flight; the Tenant, its keys and the Project link are kept |
528
+ | Deletes | all the Tenant's data: volumes, `tenant/` and the vault key; the next `start` creates it anew, with a new id, and relinks the project | the sessions (the default), the Agents with their vaults, disks and sessions (`--agents`) or all the data (`--all`) after draining work in flight; the Tenant, its keys and the Project link are kept |
481
529
 
482
530
  `nylorun tenant reset --all` asks first; pass `--yes` when not in a terminal.
483
531
  `nylorun local reset` asks too, or takes `--yes`.
@@ -558,7 +606,7 @@ them. The Runtime's own are `NYLORUN_TUNING`, which `nylorun start` passes on.
558
606
  | 0 | Success |
559
607
  | 1 | Generic failure, including a missing Docker or Compose v2 |
560
608
  | 2 | Usage error (including no Tenant selected, or `local delete` without `--yes`), or a removed or moved command |
561
- | 3 | `status`: the Runtime is not answering; `tenant`, `environments`, `local sandbox`: the local Tenant is not running; `stop`/`local logs`: no Tenant yet; `local delete`: no such Tenant; `start`: a Tenant created by nylorun 0.5 (reset it) |
609
+ | 3 | `status`: the Runtime is not answering; `tenant`, `agents`, `apply`, `local sandbox`: the local Tenant is not running; `stop`/`local logs`: no Tenant yet; `local delete`: no such Tenant; `start`: a Tenant created by nylorun 0.5 (reset it) |
562
610
  | 4 | The Runtime port is held by another Host |
563
611
  | 5 | `up`/`start`/`studio`: this nylorun pins a Runtime older than the one that last ran the Tenant; update nylorun, or `start --allow-downgrade` |
564
612
  | 7 | The containers, the Tenant or Studio did not become ready (an unavailable Tenant's cause is printed) |
@@ -577,7 +625,7 @@ them. The Runtime's own are `NYLORUN_TUNING`, which `nylorun start` passes on.
577
625
  | Studio login expired | `nylorun studio` |
578
626
  | Which Studio is which | `nylorun local ls` lists each Tenant's Studio URL; `nylorun studio --tenant <name>` opens one signed in |
579
627
  | `Tenant … was created by nylorun 0.5` (exit 3) | `nylorun local reset --tenant <name>` (its data starts fresh) |
580
- | `tenant` or `environments`: the Tenant is not running or not open | `npx nylorun start`, then `npx nylorun status`, which shows the cause and its `repair` |
628
+ | `tenant`, `agents` or `apply`: the Tenant is not running or not open | `npx nylorun start`, then `npx nylorun status`, which shows the cause and its `repair` |
581
629
  | No management key for a remote installation | Set `NYLORUN_MANAGEMENT_KEY`; on the Runtime's machine `nylorun tenant keys put <id> --management` issues one |
582
630
  | `403 key_role_mismatch` | The key belongs to the other API: a management key for the Management API, an application key for the Runtime API |
583
631
  | Old Project link refused | `npx nylorun start` in the project |
package/dist/cli.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import "./baseline.js";
3
3
  import { baselineEnv } from "./baseline.js";
4
4
  import { refuseNativeWindows, runCommand } from "./command.js";
5
- import { CliError } from "./errors.js";
5
+ import { CliError, HelpRequest, isHelp } from "./errors.js";
6
6
  import { defaultStackDeps, stackCommand, stackUsage, studioCommand } from "./stack/index.js";
7
7
  const usage = `nylorun <command>
8
8
 
@@ -12,14 +12,25 @@ ${stackUsage}
12
12
  doctor sandbox [--tenant <name>] [--json]
13
13
  the sandbox backend the Tenant's Host offers
14
14
 
15
+ Agent manifests:
16
+ apply [<dir>...] [--dry-run] [--if-match <n>]
17
+ save the agent manifest each folder's agent.manifest.json
18
+ describes, with the files it names (Runtime API)
19
+ migrate v8 <agent.json> [--runtime <environment-manifest.json>] [--name <name>] [--out <dir>]
20
+ write the three manifest files from an agent manifest v7
21
+ and an environment manifest v1 (reads no Runtime)
22
+
15
23
  Groups, each with its own --help:
16
- agents list | get | save the Tenant's agents (Runtime API, an application key)
24
+ agent-manifests list | get | versions | rm
25
+ the Tenant's agent manifests (Runtime API)
26
+ agents list | get | put | pin | track | restart | fork | stop | reset | rm |
27
+ snapshot | restore | versions | delete-version | events | secrets |
28
+ triggers | runs | memories
29
+ the Tenant's Agents, made from saved manifests; sessions
30
+ run on them (Runtime API)
17
31
  sessions list | create | get | send | approve | respond | cancel | watch | history
18
32
  usage | calls | trace | exec
19
33
  the Tenant's sessions (Runtime API)
20
- environments list | get | put | fork | stop | reset | delete | snapshot | restore
21
- versions | delete-version | events | secrets | manifests
22
- the Tenant's Environments (Runtime API)
23
34
  artifacts list | get | upload | download | tree | diff | zip | link | rm
24
35
  the Tenant's file artifacts (Runtime API)
25
36
  tenant reset | keys | signing-keys | models | usage | calls | budgets | tool-policy |
@@ -32,7 +43,8 @@ A command acts on the local Tenant --tenant names, else the linked project's, el
32
43
  project) the default Tenant; NYLORUN_HOME sets its Host root (default
33
44
  ~/.nylorun/tenants/<name>). Without --tenant, NYLORUN_RUNTIME_URL names a remote installation:
34
45
  with NYLORUN_MANAGEMENT_KEY for status, doctor sandbox and tenant; with NYLORUN_SERVER_KEY, or an
35
- identity provider's token in NYLORUN_TOKEN, for agents, sessions, environments and artifacts.
46
+ identity provider's token in NYLORUN_TOKEN, for apply, agent-manifests, agents, sessions and
47
+ artifacts.
36
48
  The Runtime API groups act for a person with --as <subject> [--scope <scope>]...`;
37
49
  const localUsage = `nylorun local <command>
38
50
 
@@ -54,7 +66,8 @@ const MOVED = {
54
66
  ls: "nylorun ls moved: nylorun local ls",
55
67
  delete: "nylorun delete moved: nylorun local delete",
56
68
  telemetry: "nylorun telemetry moved: nylorun local telemetry",
57
- reset: "nylorun reset moved: nylorun local reset deletes a local Tenant's volumes; nylorun tenant reset clears its sessions or Environments through the Management API",
69
+ reset: "nylorun reset moved: nylorun local reset deletes a local Tenant's volumes; nylorun tenant reset clears its sessions or Agents through the Management API",
70
+ environments: "nylorun environments is nylorun agents in protocol 16: Environments are Agents, made from saved agent manifests (nylorun apply). Environment manifests are the runtime section of an agent manifest (nylorun migrate v8).",
58
71
  key: "nylorun key moved: nylorun tenant keys put|list|rm",
59
72
  keys: "nylorun keys is nylorun tenant keys put|list|rm",
60
73
  mcp: "nylorun mcp moved: nylorun tenant mcp inspect <url>",
@@ -66,10 +79,10 @@ const MOVED = {
66
79
  runtime: "nylorun runtime was removed: the local Runtime runs in Docker Compose. Use nylorun up|down|status and nylorun local logs.",
67
80
  };
68
81
  const SANDBOX_MOVED = {
69
- ls: "nylorun sandbox ls moved: nylorun environments list",
70
- list: "nylorun sandbox ls moved: nylorun environments list",
71
- rm: "nylorun sandbox rm moved: nylorun environments delete <id>",
72
- delete: "nylorun sandbox rm moved: nylorun environments delete <id>",
82
+ ls: "nylorun sandbox ls moved: nylorun agents list",
83
+ list: "nylorun sandbox ls moved: nylorun agents list",
84
+ rm: "nylorun sandbox rm moved: nylorun agents rm <id>",
85
+ delete: "nylorun sandbox rm moved: nylorun agents rm <id>",
73
86
  };
74
87
  const LOCAL_UI_REMOVED = "--local-ui was removed: Studio runs in its own container. Run nylorun studio.";
75
88
  const usageError = (message) => new CliError(message, 2);
@@ -150,11 +163,18 @@ async function main() {
150
163
  process.exitCode = await tenantCommand(defaultStackDeps(env), args);
151
164
  return;
152
165
  }
153
- if (command === "agents" || command === "sessions" || command === "environments" || command === "artifacts") {
166
+ if (command === "apply" ||
167
+ command === "migrate" ||
168
+ command === "agent-manifests" ||
169
+ command === "agents" ||
170
+ command === "sessions" ||
171
+ command === "artifacts") {
154
172
  const group = {
173
+ apply: async () => (await import("./client/apply.js")).applyCommand,
174
+ migrate: async () => (await import("./client/migrate.js")).migrateCommand,
175
+ "agent-manifests": async () => (await import("./client/agent-manifests.js")).agentManifestsCommand,
155
176
  agents: async () => (await import("./client/agents.js")).agentsCommand,
156
177
  sessions: async () => (await import("./client/sessions.js")).sessionsCommand,
157
- environments: async () => (await import("./client/environments.js")).environmentsCommand,
158
178
  artifacts: async () => (await import("./client/artifacts.js")).artifactsCommand,
159
179
  }[command];
160
180
  process.exitCode = await (await group())(defaultStackDeps(env), args);
@@ -164,6 +184,8 @@ async function main() {
164
184
  const [topic, ...options] = args;
165
185
  if (topic === "sandbox") {
166
186
  const usage = "Usage: nylorun doctor sandbox [--tenant <name>] [--json]";
187
+ if (options.some(isHelp))
188
+ throw new HelpRequest(usage);
167
189
  const tenantAt = options.indexOf("--tenant");
168
190
  const tenant = tenantAt < 0 ? undefined : options[tenantAt + 1];
169
191
  const rest = options.filter((_, index) => index !== tenantAt && index !== tenantAt + 1);
@@ -176,8 +198,11 @@ async function main() {
176
198
  });
177
199
  return;
178
200
  }
201
+ const usage = "Usage: nylorun doctor [--json] | nylorun doctor sandbox [--tenant <name>] [--json]";
202
+ if (args.some(isHelp))
203
+ throw new HelpRequest(usage);
179
204
  if (args.some((option) => option !== "--json"))
180
- throw usageError("Usage: nylorun doctor [--json] | nylorun doctor sandbox [--tenant <name>] [--json]");
205
+ throw usageError(usage);
181
206
  const { doctorStack } = await import("./doctor.js");
182
207
  process.exitCode = await doctorStack({ json: args.includes("--json"), env });
183
208
  return;
@@ -0,0 +1,4 @@
1
+ import type { StackDeps } from "../stack/commands.js";
2
+ export declare const agentManifestsUsage: string;
3
+ /** `nylorun agent-manifests <command> ...` */
4
+ export declare function agentManifestsCommand(deps: StackDeps, args: readonly string[]): Promise<number>;