nylorun 0.19.0-beta → 0.21.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 CHANGED
@@ -1,5 +1,80 @@
1
1
  # nylorun
2
2
 
3
+ ## 0.21.0-beta
4
+
5
+ ### Minor Changes
6
+
7
+ - 95f98f1: A model can use the Host's own identity (ADR-71, Host feature `model-host-identity`). `PUT /v1/tenant/model` takes `auth: { type: "host_identity", project, location }` for `google-vertex`. It keeps no secret, and the model gate calls Agent Platform with the Host's Google Application Default Credentials: on Google Cloud, the attached service account from the metadata server. It's off unless the operator lists the provider in `NYLORUN_MODEL_HOST_IDENTITY` on the process that runs the gates, which `nylorun start` passes from its shell to the `gateway` container. Every Tenant on that Host may use it. `nylorun tenant models set --provider google-vertex --model <id> --host-identity --project <id> --location <location>` sets it with no key.
8
+
9
+ ### Patch Changes
10
+
11
+ - 683de1a: The model catalog comes from pi-ai 1.3.0, which adds Gemini 4 Argon: `google-vertex/gemini-4-argon` on Google's Agent Platform (Vertex AI) and `google/gemini-4-argon` on the Gemini API, with a 1,048,576-token context and thinking. `nylorun tenant models set --provider google-vertex --model gemini-4-argon` takes a Google Cloud API key for the Agent Platform API; the Runtime still reads no ambient Google credentials.
12
+ - Pin core to the tested release.
13
+ - Pin agents to the tested release.
14
+ - Pin admin to the tested release.
15
+ - Pin runtime to the tested release.
16
+ - Pin studio to the tested release.
17
+ - Updated dependencies [95f98f1]
18
+ - Updated dependencies [d99b3ac]
19
+ - Updated dependencies
20
+ - Updated dependencies
21
+ - @nylorun/core@0.29.0-beta
22
+ - @nylorun/agents@0.29.0-beta
23
+ - @nylorun/admin@0.19.5-beta
24
+
25
+ ## 0.20.0-beta
26
+
27
+ ### Minor Changes
28
+
29
+ - 498d972: `nylorun check --fix` makes the edits the compiler's diagnostics carry (track T7). A diagnostic one edit fixes has a `fix` (`AgentFolderFix`, in `AgentFolderDiagnostic` and the Runtime API's): `rename_key` for an unknown key with exactly one did-you-mean (in `AGENT.md`, a trigger, a `SKILL.md`, a tool file, `runtime.json`, `mcp.json`, `flow.json` and a JSON Schema's keywords), at its line and column, and none when two keys are as close or the key it would be is already there; `crlf` for a file with CRLF line ends, which is now a `crlf` note (it is read as LF, as before); and `move_skill_secrets` for `secrets` in a root skill's `SKILL.md`, when `AGENT.md` lists none for the skill, or lists them all. Messages, manifests and hashes are unchanged. `applyFolderFixes` in `@nylorun/core/folder` makes them on text: the key token renamed with every other byte kept, LF line ends, and the secrets moved to `AGENT.md`'s `skills` block as `migrate folder` writes it, skipping (with why) a fix whose text is no longer where it was.
30
+
31
+ `nylorun check` marks each fixable problem `(fixable with --fix)` and writes nothing. `check --fix` makes the edits in the folder's files, prints each change by file, and checks again until nothing is left to fix; it leaves a file whose bytes changed since it was checked (writing nothing when one changes while it fixes), and a `runtime.json` that `extends` another. `check --json` gives each diagnostic's `fix`, and with `--fix` each folder's `fixed` and `unfixed`.
32
+
33
+ - b3dad06: Agent folders convert both ways (track T7, D80). `folderOfManifest(manifest)` in `@nylorun/core/folder` (also exported by `@nylorun/agents`) writes the agent folder that compiles back to the same manifest: name, description, metadata, harness, memory, loop and server and skill settings in `AGENT.md`, the first instruction as its body and the rest as `instructions/NN-*.md`, HTTP tools as `tools/<name>.json`, subagents as `agents/<name>/`, a flow as `flow.json` (v3's node tree, naming agents by id and tools by file name) with one flat `agents/<id>/` for its agents and its sub-flows' (a sub-flow is an `agents/<id>/` with its own `flow.json`, and a tool stage or HTTP verifier a `tools/<name>.json` beside the `flow.json` that names it), MCP servers in `mcp.json` with `Bearer ${SLOT}` or `${SLOT}` for a credential, triggers as `triggers/<id>.md`, and `runtime.json` without the slots the compiler derives the same way. It checks itself by compiling the folder, says whether the hash is the same (`exact`), and notes what it writes differently. Skills are written from their bytes when given them, else as a placeholder with the files to copy in. An embedded agent's display `name` is left out with a note, since a folder names an agent by its id.
34
+
35
+ `nylorun export --folder <name>[@<version>]` writes the folder of a saved manifest, from JSON or TypeScript; `nylorun migrate folder <dir>` writes the folder of a three-file folder, offline, with its skills; `nylorun pull <name>[@<version>]` writes back the folder a version was saved from, byte for byte, and says to use `export --folder` for a version saved as JSON. None writes over a file with other bytes.
36
+
37
+ Deprecated, still read: the three-file format (`agent.manifest.json`), whose `composeManifest` and `nylorun apply` now warn and name `nylorun migrate folder`, and `secrets` in a `SKILL.md`, which the skills loader warns about (a `DeprecationWarning` from `.skills()`): an agent folder lists a skill's secrets in `AGENT.md`.
38
+
39
+ - b3dad06: Both ends of the agent folder loop (track T7).
40
+
41
+ - `nylorun init <path>` names the agent after the path's last segment (`init agents/hello`). `--example` adds `tools/get_order.json`, `mcp.json` (a `Bearer ${ORDERS_MCP_TOKEN}` header) and `triggers/new-order.md`, explained in the folder's README.md, and the result passes `nylorun check`. The first run in a project (the nearest directory with `.git`) writes `.gitattributes` (`* text=auto eol=lf`), ignores `.nylorun/credentials.json` in `.gitignore`, and maps the folder files to their JSON Schemas in `.vscode/settings.json`, merged into an existing file. Its hint names `apply --agent` and `chat`.
42
+ - `nylorun apply --agent [<id>]` makes the Agent from the manifest after a save (or on an unchanged one), or moves it, as `nylorun agents put` does, and prints what it needs a person for.
43
+ - `nylorun apply --watch [--save]` checks and plans again on each change to the folders (and the files their `runtime.json` extends); it saves only with `--save`.
44
+ - A plan's change to the instructions prints their text diff, `-` and `+` lines.
45
+ - `nylorun chat <agent> [--session <id>] [--message <text>]` opens or reuses a session, sends `--message` or each line of standard input, and prints the reply as it comes.
46
+ - `nylorun check --json` prints `{ folders: [{ path, ok, manifest?, diagnostics }] }` for CI, with the same exit codes. `check` says "1 file", and `nylorun --version` prints the version.
47
+ - `packFolder` (`@nylorun/agents`) leaves out what the folder's `.nyloignore` names (gitignore rules), and resolves `extends` in `runtime.json`: the packed file is the merge, the folder's own keys winning, with `.nylorun/origin.json` naming the files it came from; a missing file or a cycle is a `FolderError`. `ignoreMatcher` is exported.
48
+ - `session.approve(id, approved)` and `session.respond(id, value)` take no options: each makes its own idempotency key.
49
+ - The Runtime's Agent view names each required secret of the version it runs that has no value, as an attention item (`secret_unset: required secret ORDERS_TOKEN unset`, state `input_required`), until it is set.
50
+ - The compiler's refusal of an unresolved `extends` says to resolve it before uploading.
51
+
52
+ ### Patch Changes
53
+
54
+ - 498d972: `@nylorun/agents` exports `harnessSectionOf` and `sectionGaps` from its main entry, as its README documents: the harness section `agentManifests.save` makes from a built agent or flow, and the gaps the Runtime refuses between a manifest's two sections. Both were only in `@nylorun/agents/define` and `@nylorun/core/define`.
55
+
56
+ `nylo` no longer says nylorun 0.19 removes it, which 0.19 does not: its message ends "A later nylorun release removes nylo."
57
+
58
+ - Pin core to the tested release.
59
+ - Pin agents to the tested release.
60
+ - Pin admin to the tested release.
61
+ - Pin runtime to the tested release.
62
+ - Pin studio to the tested release.
63
+ - Updated dependencies [7bcdc85]
64
+ - Updated dependencies [498d972]
65
+ - Updated dependencies [498d972]
66
+ - Updated dependencies [d23304e]
67
+ - Updated dependencies [b3dad06]
68
+ - Updated dependencies [b3dad06]
69
+ - Updated dependencies [b3dad06]
70
+ - Updated dependencies [498d972]
71
+ - Updated dependencies [b3dad06]
72
+ - Updated dependencies
73
+ - Updated dependencies
74
+ - @nylorun/core@0.28.0-beta
75
+ - @nylorun/agents@0.28.0-beta
76
+ - @nylorun/admin@0.19.4-beta
77
+
3
78
  ## 0.19.0-beta
4
79
 
5
80
  ### Minor Changes
package/README.md CHANGED
@@ -53,10 +53,14 @@ nylorun doctor sandbox [--tenant <name>] [--json] # the sandbox backend the Te
53
53
 
54
54
  # apply, agent-manifests, agents, sessions, artifacts: the Runtime API (an application key, or NYLORUN_TOKEN)
55
55
  # every one takes --tenant <name>, and --as <subject> [--scope <scope>]... to act for a person
56
- nylorun init <name> [--description <text>] # write <name>/AGENT.md, a new agent folder
57
- nylorun check [<dir>...] # compile each agent folder offline: every problem by file, line and column
58
- nylorun apply [<dir>...] [--dry-run] [--if-match <n>] # plan, then save each folder (AGENT.md or agent.manifest.json), its files uploaded
56
+ nylorun init <path> [--description <text>] [--example] # write <path>/AGENT.md, a new agent folder named after the last segment
57
+ nylorun check [<dir>...] [--fix] [--json] # compile each agent folder offline: every problem by file, line and column; --fix makes the fixable ones' edits
58
+ nylorun apply [<dir>...] [--dry-run] [--if-match <n>] [--agent [<id>]] [--watch [--save]] # plan, then save each folder (AGENT.md or agent.manifest.json), its files uploaded
59
+ nylorun chat <agent> [--session <id>] [--message <text>] # send each line (or --message), print each reply
59
60
  nylorun migrate v8 <agent.json> [--runtime <environment-manifest.json>] [--name <name>] [--out <dir>] # the three files from a v7 manifest; reads no Runtime
61
+ nylorun migrate folder <dir> [--out <dir>] # the agent folder of a three-file folder; reads no Runtime
62
+ nylorun export --folder <name>[@<n>] [--out <dir>] # the agent folder of a saved manifest (JSON or TypeScript)
63
+ nylorun pull <name>[@<n>] [--out <dir>] # the folder a version was saved from, byte for byte
60
64
  nylorun agent-manifests list [--json] # name, latest version, runtime kind, harness, Agents
61
65
  nylorun agent-manifests get <name>[@<n>] | versions <name> | rm <name>
62
66
  nylorun agents list [--state <s>] [--manifest <name>] [--label <key=value>]... [--outdated] [--limit <n>] [--cursor <c>] [--json] # --outdated (or --behind): moving to another manifest version
@@ -98,6 +102,7 @@ nylorun tenant signing-keys list|rotate [--force]|revoke <kid> [--tenant <name>]
98
102
  nylorun tenant models catalog|providers|get [--tenant <name>] [--json] # the models the Runtime knows, the providers with a credential, the Tenant's model
99
103
  nylorun tenant models set [--tenant <name>] # sign in to a model provider and set the Tenant's model
100
104
  nylorun tenant models set --provider <id> --model <id> [--base-url <url>] [--tenant <name>] # the same, with an API key piped in on stdin (CI)
105
+ nylorun tenant models set --provider google-vertex --model <id> --host-identity --project <id> --location <location> # the Host's Google identity, no key
101
106
  nylorun tenant models select <provider> [--model <id>] [--tenant <name>] # use another provider that has a credential
102
107
  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>
103
108
  nylorun tenant calls [--after <cursor>] [--limit <n>] [--tenant <name>] # every recorded model call as NDJSON, until caught up
@@ -132,8 +137,8 @@ apply`; `nylorun configure` is `nylorun tenant models set`. `nylorun dev`,
132
137
  are gone.
133
138
 
134
139
  The package's second command, `nylo`, was the Runtime client until nylorun took
135
- its commands. Until nylorun 0.19, which removes it, it names the `nylorun`
136
- command that replaced each of its own and exits 2:
140
+ its commands. It still ships, and a later release removes it: it names the
141
+ `nylorun` command that replaced each of its own and exits 2:
137
142
 
138
143
  | `nylo` | `nylorun` |
139
144
  | --- | --- |
@@ -478,25 +483,163 @@ from a terminal.
478
483
  An agent runs from a saved **agent manifest** (protocol 16): one named, versioned
479
484
  document with a harness section (instructions, tools, skills, MCP servers,
480
485
  plugins) and a runtime section (kind, image, network, setup, files, secret
481
- slots). Author it as an agent folder (track T6), one folder per agent:
486
+ slots). Author it as an agent folder (tracks T6 and T7), one folder per agent:
482
487
 
483
488
  ```
484
489
  agents/support/AGENT.md # frontmatter (name, description), then the instructions
485
490
  agents/support/mcp.json # MCP servers; "Authorization": "Bearer ${GITHUB_TOKEN}" names a slot
486
491
  agents/support/runtime.json # kind, network, secrets (optional)
487
492
  agents/support/skills/<skill>/SKILL.md, tools/<tool>.json, triggers/<id>.md, files/**
493
+ agents/support/agents/<id>/ # a subagent, offered to support as the tool <id>
494
+ agents/support/plugins/<name>/ # a vendored Agent Plugin: its skills and mcp.json servers
488
495
  ```
489
496
 
490
- `nylorun init support` writes the `AGENT.md`; `nylorun check agents/support`
497
+ A small one, with an HTTP tool and GitHub's MCP server. `AGENT.md`:
498
+
499
+ <!-- doc-test: folder support AGENT.md -->
500
+ ```markdown
501
+ ---
502
+ name: support
503
+ description: Answers questions about a customer's orders.
504
+ ---
505
+ Answer questions about the customer's orders. Look an order up with lookup_order before you
506
+ answer a question about it. When the customer reports a bug, find the matching GitHub issue.
507
+ ```
508
+
509
+ `tools/lookup_order.json`, an HTTP tool named after its file. `credential` names
510
+ the secret slot `ORDERS_TOKEN`, sent as a bearer token, never a value:
511
+
512
+ <!-- doc-test: folder support tools/lookup_order.json -->
513
+ ```json
514
+ {
515
+ "description": "Look up one order by its id: its status, items and total.",
516
+ "inputSchema": {
517
+ "type": "object",
518
+ "properties": { "orderId": { "type": "string", "description": "The order's id, such as A-1001." } },
519
+ "required": ["orderId"],
520
+ "additionalProperties": false
521
+ },
522
+ "http": { "url": "https://orders.example.com/lookup", "method": "POST", "credential": "ORDERS_TOKEN" }
523
+ }
524
+ ```
525
+
526
+ `mcp.json`, in Agent Plugins syntax; `${GITHUB_TOKEN}` names the slot the
527
+ server authenticates with:
528
+
529
+ <!-- doc-test: folder support mcp.json -->
530
+ ```json
531
+ {
532
+ "mcpServers": {
533
+ "github": {
534
+ "type": "streamable-http",
535
+ "url": "https://api.githubcopilot.com/mcp/",
536
+ "headers": { "Authorization": "Bearer ${GITHUB_TOKEN}" }
537
+ }
538
+ }
539
+ }
540
+ ```
541
+
542
+ With no `runtime.json`, the compiler derives both slots (`ORDERS_TOKEN` and
543
+ `GITHUB_TOKEN`, each bound to its URL) and says so; write their values with
544
+ `nylorun agents secrets put support <name>`.
545
+
546
+ `nylorun init agents/support` writes the `AGENT.md`; `nylorun check agents/support`
491
547
  compiles the folder offline with the Runtime's compiler and prints every problem
492
548
  as `file:line:column severity: message`, exiting 1 when it does not compile.
549
+ A problem one edit fixes ends `(fixable with --fix)`: an unknown key with one
550
+ did-you-mean (`memmory` for `memory`), CRLF line ends, and `secrets` in a
551
+ `SKILL.md`. `nylorun check --fix agents/support` makes those edits, and only
552
+ those: it renames the key where it is, keeping every other byte; makes the line
553
+ ends LF; and moves the secrets to `AGENT.md`'s `skills` block, as
554
+ `nylorun migrate folder` writes it. It prints each change, then checks again. It
555
+ leaves a file whose bytes changed since it was checked, and a `runtime.json`
556
+ that `extends` another; without `--fix`, `check` writes nothing.
493
557
  `nylorun apply agents/support` checks it the same way (sending nothing when it
494
558
  does not compile), plans it, prints the compiler's notes (such as a slot derived
495
559
  from `mcp.json`) and saves it, uploading its files by hash; the Runtime keeps the
496
560
  folder as the version's source. `--dry-run` also prints the compiled manifest. A
497
561
  change only to a file outside the agent, such as a README, is `unchanged`.
498
562
 
499
- Or as three files:
563
+ The loop from an empty folder to an answer:
564
+
565
+ ```
566
+ nylorun init agents/hello --example # AGENT.md, tools/, mcp.json and triggers/, each explained in its README.md
567
+ nylorun apply agents/hello --agent # save it, then make the Agent hello from it (or move it to the new version)
568
+ nylorun chat hello # send each line, print each reply; --message <text> sends one
569
+ ```
570
+
571
+ `init <path>` names the agent after the path's last segment. The first run in a
572
+ project (the nearest directory with `.git`) also writes `.gitattributes`
573
+ (`* text=auto eol=lf`), ignores `.nylorun/credentials.json` in `.gitignore`, and
574
+ maps the folder files to their JSON Schemas in `.vscode/settings.json`, merged
575
+ into the file that is there. `check --json` prints
576
+ `{ "folders": [{ path, ok, manifest?, diagnostics }] }` for CI, each fixable
577
+ diagnostic with its `fix`; with `--fix`, each folder also lists what was `fixed`
578
+ and what was `unfixed`, with why. A plan's change
579
+ to the instructions prints their text diff. `apply --watch` checks and plans
580
+ again on each change, and saves only with `--save` (for a development manifest:
581
+ each save is a new version that moves the Agents tracking it).
582
+
583
+ `.nyloignore` in a folder names, in gitignore syntax, what packing leaves out.
584
+ `runtime.json` may say `"extends": "../../platform/pod.runtime.json"`: `apply`
585
+ and `check` merge that file under it (the folder's keys win, objects merge,
586
+ arrays replace), send the merged `runtime.json`, and name the files it came from
587
+ in `.nylorun/origin.json`.
588
+
589
+ A folder with `flow.json` is a flow: its stages name agents of the folder's one
590
+ `agents/` by id (an `agents/<id>/` with a `flow.json` of its own is a sub-flow),
591
+ `"tool": "<name>"` names `tools/<name>.json` beside the `flow.json`, and its
592
+ `AGENT.md` has frontmatter only (and may set `inputSchema`). A two-stage chain:
593
+
594
+ <!-- doc-test: folder brief AGENT.md -->
595
+ ```markdown
596
+ ---
597
+ name: brief
598
+ description: Researches a topic, then writes a short brief on it.
599
+ ---
600
+ ```
601
+
602
+ <!-- doc-test: folder brief flow.json -->
603
+ ```json
604
+ { "chain": [{ "agent": "researcher" }, { "agent": "writer" }] }
605
+ ```
606
+
607
+ <!-- doc-test: folder brief agents/researcher/AGENT.md -->
608
+ ```markdown
609
+ ---
610
+ name: researcher
611
+ description: Lists what matters about the topic.
612
+ ---
613
+ List the five facts about the topic a newcomer most needs, each with one sentence of context.
614
+ ```
615
+
616
+ <!-- doc-test: folder brief agents/writer/AGENT.md -->
617
+ ```markdown
618
+ ---
619
+ name: writer
620
+ description: Writes the brief.
621
+ ---
622
+ Write a brief of at most 200 words from the facts you are given, for a reader new to the topic.
623
+ ```
624
+
625
+ [`examples/agents/repo-brief-folder/`](../../examples/agents/repo-brief-folder/)
626
+ is a whole flow as a folder: a switch, a map, a parallel stage, a loop and an HTTP
627
+ tool stage. Without `flow.json`, each `agents/<id>/` is a subagent: the agent
628
+ calls it as the tool `<id>` with `{ task }`, one level deep. `plugins/<name>/`
629
+ folds a plugin's skills and `mcp.json` servers in as `.plugin()` does, and notes
630
+ what Nylorun does not run (hooks, commands).
631
+
632
+ `nylorun pull support[@3] [--out <dir>]` writes back the folder a version was
633
+ saved from, byte for byte. A version saved as JSON or from TypeScript has none:
634
+ `nylorun export --folder support[@3] [--out <dir>]` writes its folder from the
635
+ manifest instead (instructions as Markdown, tools, `mcp.json`, triggers,
636
+ `runtime.json`, subagents as `agents/<id>/`, and a flow as `flow.json` with its
637
+ agents), says whether it compiles back to the same manifest, and notes what it
638
+ writes differently (a skill's files, which the manifest names by hash only, are
639
+ left to copy in). Neither writes over a file with other bytes.
640
+
641
+ Or as three files (deprecated: `apply` warns, and `nylorun migrate folder
642
+ agents/triage --out <dir>` writes the agent folder, with its skills, offline):
500
643
 
501
644
  ```
502
645
  agents/triage/agent.manifest.json # { "manifestSchemaVersion": 8, "name": "triage",
@@ -519,8 +662,9 @@ against, uploading the files the Runtime does not hold (`PUT /v1/files/sha256:
519
662
  A manifest whose sections do not fit, or whose runtime misses what its harness
520
663
  `requires`, is an error: nothing is saved and the command exits 1. `--dry-run`
521
664
  prints the plans only; `--if-match <n>` saves only over version `n`.
522
- `nylorun apply agents/` applies every subfolder with an `agent.manifest.json`;
523
- every folder composes before anything is sent.
665
+ `nylorun apply agents/` applies every subfolder with an `AGENT.md` (or an
666
+ `agent.manifest.json`); every folder compiles, or composes, before anything is
667
+ sent.
524
668
 
525
669
  `nylorun agent-manifests list` shows each manifest's latest version, runtime
526
670
  kind, harness and the Agents made from it; `get <name>[@<n>]` prints a version,
@@ -536,7 +680,8 @@ manifest's fields become the runtime file, its `harness` the harness file's `id`
536
680
  and v7's `requires` stays in the harness file for `apply` to check. With no
537
681
  environment manifest the kind is `pod` when the agent requires one, `virtual`
538
682
  when it has skills or requires a sandbox, else `none`. It overwrites no file and
539
- prints the gaps to fix before `apply`.
683
+ prints the gaps to fix before `apply`. The three files are deprecated: `nylorun
684
+ migrate folder agents/triage --out <dir>` then writes them as an agent folder.
540
685
 
541
686
  ### `local reset` or `tenant reset`
542
687
 
@@ -573,6 +718,15 @@ providers need the prompts.
573
718
  printenv OPENAI_API_KEY | nylorun tenant models set --provider openai --model gpt-5
574
719
  ```
575
720
 
721
+ On a Host whose operator lends its identity (`NYLORUN_MODEL_HOST_IDENTITY=google-vertex`),
722
+ `--host-identity` with `--project` and `--location` sets a `google-vertex` model with no key: the
723
+ Runtime calls Agent Platform with the Host's Google Application Default Credentials.
724
+
725
+ ```sh
726
+ nylorun tenant models set --provider google-vertex --model gemini-4-argon \
727
+ --host-identity --project my-project --location global
728
+ ```
729
+
576
730
  `nylorun tenant models select <provider>` switches to another provider that
577
731
  already has a credential, keeping its model (or `--model`) and endpoint.
578
732
 
package/dist/cli.js CHANGED
@@ -13,15 +13,29 @@ ${stackUsage}
13
13
  the sandbox backend the Tenant's Host offers
14
14
 
15
15
  Agent manifests:
16
- init <name> [--description <text>] write <name>/AGENT.md, a new agent folder
17
- check [<dir>...] compile each agent folder offline and print every problem
18
- by file, line and column (reads no Runtime)
19
- apply [<dir>...] [--dry-run] [--if-match <n>]
16
+ init <path> [--description <text>] [--example]
17
+ write <path>/AGENT.md, a new agent folder named after the
18
+ path's last segment; --example adds a tool, mcp.json and a
19
+ trigger
20
+ check [<dir>...] [--fix] [--json] compile each agent folder offline and print every problem
21
+ by file, line and column (reads no Runtime); --fix makes
22
+ the edits the fixable ones name
23
+ apply [<dir>...] [--dry-run] [--if-match <n>] [--agent [<id>]] [--watch [--save]]
20
24
  save the agent manifest each folder describes (its AGENT.md,
21
- or its agent.manifest.json), with its files (Runtime API)
25
+ or its agent.manifest.json), with its files (Runtime API);
26
+ --agent then makes or moves the Agent; --watch plans again
27
+ on each change
28
+ chat <agent> [--session <id>] [--message <text>]
29
+ talk to an Agent: send each line, print each reply
22
30
  migrate v8 <agent.json> [--runtime <environment-manifest.json>] [--name <name>] [--out <dir>]
23
31
  write the three manifest files from an agent manifest v7
24
32
  and an environment manifest v1 (reads no Runtime)
33
+ migrate folder <dir> [--out <dir>] write the agent folder of a three-file folder
34
+ (agent.manifest.json; reads no Runtime)
35
+ export --folder <name>[@<version>] [--out <dir>]
36
+ write the agent folder of a saved manifest (Runtime API)
37
+ pull <name>[@<version>] [--out <dir>]
38
+ write the folder a version was saved from (Runtime API)
25
39
 
26
40
  Groups, each with its own --help:
27
41
  agent-manifests list | get | versions | rm
@@ -126,6 +140,10 @@ async function main() {
126
140
  const [command, ...args] = process.argv.slice(2);
127
141
  if (!command || command === "--help" || command === "-h")
128
142
  return void console.log(usage);
143
+ if (command === "--version" || command === "-v" || command === "version") {
144
+ const { cliVersion } = await import("./stack/versions.js");
145
+ return void console.log(cliVersion());
146
+ }
129
147
  refuseNativeWindows();
130
148
  if (command === "sandbox") {
131
149
  const sub = args[0];
@@ -170,6 +188,9 @@ async function main() {
170
188
  command === "check" ||
171
189
  command === "init" ||
172
190
  command === "migrate" ||
191
+ command === "export" ||
192
+ command === "pull" ||
193
+ command === "chat" ||
173
194
  command === "agent-manifests" ||
174
195
  command === "agents" ||
175
196
  command === "sessions" ||
@@ -179,6 +200,9 @@ async function main() {
179
200
  check: async () => (await import("./client/folder.js")).checkCommand,
180
201
  init: async () => (await import("./client/folder.js")).initCommand,
181
202
  migrate: async () => (await import("./client/migrate.js")).migrateCommand,
203
+ export: async () => (await import("./client/convert.js")).exportCommand,
204
+ pull: async () => (await import("./client/convert.js")).pullCommand,
205
+ chat: async () => (await import("./client/chat.js")).chatCommand,
182
206
  "agent-manifests": async () => (await import("./client/agent-manifests.js")).agentManifestsCommand,
183
207
  agents: async () => (await import("./client/agents.js")).agentsCommand,
184
208
  sessions: async () => (await import("./client/sessions.js")).sessionsCommand,
@@ -1,4 +1,22 @@
1
+ /**
2
+ * `nylorun agents`: the Tenant's Agents (protocol 16: each is one version of an agent manifest
3
+ * made live, with one environment and one vault, and the sessions that run on it), through the
4
+ * Runtime API of the installation `target.ts` picks: create or find one by id from a saved
5
+ * manifest, move it to another version (`pin`, `track`, `put`; track T3) and apply a pending one
6
+ * (`restart`), fork it, stop, reset or delete it, keep and restore versions of its disk, and
7
+ * write its secrets. The manifests themselves are `agent-manifests.ts`
8
+ * and `apply.ts`. A secret's value comes from a file or standard input, never from the command
9
+ * line, and no command reads one back. None of them starts a local Tenant.
10
+ */
11
+ import type { AgentView } from "@nylorun/agents";
1
12
  import { type StackDeps } from "../stack/commands.js";
2
13
  export declare const agentsUsage: string;
14
+ /**
15
+ * The manifest an Agent runs, as the list prints it: `name@version`, the version it moves to
16
+ * (track T3), and whether it tracks.
17
+ */
18
+ export declare function manifestOf(agent: AgentView): string;
19
+ /** What a move left pending, for a person: the version, and what it waits for. */
20
+ export declare function pendingOf(agent: AgentView): string;
3
21
  /** `nylorun agents <command> ...` */
4
22
  export declare function agentsCommand(deps: StackDeps, args: readonly string[]): Promise<number>;
@@ -72,13 +72,13 @@ const SAVE_REMOVED = "nylorun agents save was removed in protocol 16: agents run
72
72
  * The manifest an Agent runs, as the list prints it: `name@version`, the version it moves to
73
73
  * (track T3), and whether it tracks.
74
74
  */
75
- function manifestOf(agent) {
75
+ export function manifestOf(agent) {
76
76
  const name = parseAgentManifestRef(agent.manifest)?.name ?? agent.manifest;
77
77
  const target = agent.targetVersion ? ` → ${agent.targetVersion}` : "";
78
78
  return `${name}@${agent.resolvedVersion}${target} ${agent.tracking === "tracking" ? "tracks" : "pinned"}`;
79
79
  }
80
80
  /** What a move left pending, for a person: the version, and what it waits for. */
81
- function pendingOf(agent) {
81
+ export function pendingOf(agent) {
82
82
  if (!agent.targetVersion)
83
83
  return "";
84
84
  return agent.waitingFor === "secrets"
@@ -0,0 +1,14 @@
1
+ import { type AgentView, type AgentsClient } from "@nylorun/agents";
2
+ import type { StackDeps } from "../stack/commands.js";
3
+ /**
4
+ * `--agent [<id>]`, or `--agent=<id>`, taken out of `args`. The word after `--agent` is its id
5
+ * unless it is a flag or names a directory under `cwd` (a folder to apply).
6
+ */
7
+ export declare function takeAgentFlag(args: readonly string[], cwd: string): {
8
+ args: string[];
9
+ agent?: {
10
+ id?: string;
11
+ };
12
+ };
13
+ /** Makes Agent `id` from manifest `name`, or moves it to the manifest's latest version, and says which. */
14
+ export declare function putAgent(deps: StackDeps, client: AgentsClient, label: string, id: string, name: string): Promise<AgentView>;
@@ -0,0 +1,71 @@
1
+ /**
2
+ * `nylorun apply --agent [<id>]` (track T7): after a manifest is saved, or found unchanged, make the
3
+ * Agent that runs it, or move it to the latest version, as `nylorun agents put <id> --manifest
4
+ * <name>` does. The id defaults to the manifest's name. What happened is printed, with what the
5
+ * Agent needs a person for (an unset required secret).
6
+ */
7
+ import { statSync } from "node:fs";
8
+ import { resolve } from "node:path";
9
+ import { RuntimeError } from "@nylorun/agents";
10
+ import { manifestOf, pendingOf } from "./agents.js";
11
+ import { runtimeCall, usageError } from "./runtime.js";
12
+ /**
13
+ * `--agent [<id>]`, or `--agent=<id>`, taken out of `args`. The word after `--agent` is its id
14
+ * unless it is a flag or names a directory under `cwd` (a folder to apply).
15
+ */
16
+ export function takeAgentFlag(args, cwd) {
17
+ const rest = [];
18
+ let agent;
19
+ for (let index = 0; index < args.length; index += 1) {
20
+ const arg = args[index];
21
+ if (arg.startsWith("--agent=")) {
22
+ const id = arg.slice("--agent=".length);
23
+ if (id === "")
24
+ throw usageError("--agent= needs an Agent id.");
25
+ agent = { id };
26
+ continue;
27
+ }
28
+ if (arg !== "--agent") {
29
+ rest.push(arg);
30
+ continue;
31
+ }
32
+ const next = args[index + 1];
33
+ if (next !== undefined && !next.startsWith("-") && !isDirectory(resolve(cwd, next))) {
34
+ agent = { id: next };
35
+ index += 1;
36
+ }
37
+ else
38
+ agent = {};
39
+ }
40
+ return { args: rest, ...(agent ? { agent } : {}) };
41
+ }
42
+ function isDirectory(path) {
43
+ try {
44
+ return statSync(path).isDirectory();
45
+ }
46
+ catch {
47
+ return false;
48
+ }
49
+ }
50
+ /** Makes Agent `id` from manifest `name`, or moves it to the manifest's latest version, and says which. */
51
+ export async function putAgent(deps, client, label, id, name) {
52
+ let before;
53
+ try {
54
+ before = await client.agents.get(id);
55
+ }
56
+ catch (error) {
57
+ if (!(error instanceof RuntimeError && error.status === 404))
58
+ await runtimeCall(() => Promise.reject(error));
59
+ }
60
+ const agent = await runtimeCall(() => client.agents.put(id, { manifest: name }));
61
+ const what = !before
62
+ ? `Made Agent ${agent.id}`
63
+ : before.resolvedVersion !== agent.resolvedVersion || before.manifest !== agent.manifest || before.targetVersion !== agent.targetVersion
64
+ ? `Moved Agent ${agent.id} from ${manifestOf(before)}`
65
+ : `Agent ${agent.id} is unchanged`;
66
+ deps.err(`${what}: it runs ${manifestOf(agent)} on ${label}${pendingOf(agent)}.`);
67
+ for (const item of agent.attention ?? [])
68
+ if (!item.sessionId)
69
+ deps.err(` attention: ${item.reason}`);
70
+ return agent;
71
+ }
@@ -1,7 +1,14 @@
1
1
  import { type AgentManifestPlan } from "@nylorun/agents";
2
2
  import type { StackDeps } from "../stack/commands.js";
3
3
  export declare const applyUsage: string;
4
+ /** How `--watch` runs an apply (`watch.ts`). */
5
+ export interface ApplyOptions {
6
+ /** Plan, and save nothing. */
7
+ planOnly?: boolean;
8
+ /** `nylorun check` printed each folder's diagnostics already. */
9
+ checked?: boolean;
10
+ }
4
11
  /** A plan as lines: the move, then each change, warning and error. */
5
12
  export declare function planLines(plan: AgentManifestPlan): string[];
6
- /** `nylorun apply [dir…] [--dry-run] [--if-match <n>]` */
7
- export declare function applyCommand(deps: StackDeps, args: readonly string[]): Promise<number>;
13
+ /** `nylorun apply [dir…] [--dry-run] [--if-match <n>] [--agent [<id>]] [--watch [--save]]` */
14
+ export declare function applyCommand(deps: StackDeps, given: readonly string[], options?: ApplyOptions): Promise<number>;