nylorun 0.18.2-beta → 0.19.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 +40 -0
- package/README.md +22 -2
- package/dist/cli.js +9 -2
- package/dist/client/apply.js +77 -20
- package/dist/client/folder.d.ts +15 -0
- package/dist/client/folder.js +99 -0
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,45 @@
|
|
|
1
1
|
# nylorun
|
|
2
2
|
|
|
3
|
+
## 0.19.0-beta
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- aaa079f: Agent folders in the SDK and the CLI (track T6). `@nylorun/agents` adds `packFolder(dir)`, which lists a folder's files with their sizes and hashes (skipping `.git` and `node_modules`, following no symbolic link), `checkFolder`, which compiles it offline with the Runtime's compiler, and `client.agentManifests.saveFolder` and `planFolder`, which upload the files the Runtime lacks and send the folder by hash; `source` and `sourceFile` read a version's folder back. `nylorun init <name>` writes a new folder's `AGENT.md`, `nylorun check [dir…]` prints every problem by file, line and column with no Runtime, and `nylorun apply` saves a folder with `AGENT.md` (`--dry-run` prints the compiled manifest). A folder that does not compile sends nothing.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Pin core to the tested release.
|
|
12
|
+
- Pin agents to the tested release.
|
|
13
|
+
- Pin admin to the tested release.
|
|
14
|
+
- Pin runtime to the tested release.
|
|
15
|
+
- Pin studio to the tested release.
|
|
16
|
+
- Updated dependencies [9ba6634]
|
|
17
|
+
- Updated dependencies [aaa079f]
|
|
18
|
+
- Updated dependencies [aaa079f]
|
|
19
|
+
- Updated dependencies
|
|
20
|
+
- Updated dependencies
|
|
21
|
+
- @nylorun/core@0.27.0-beta
|
|
22
|
+
- @nylorun/agents@0.27.0-beta
|
|
23
|
+
- @nylorun/admin@0.19.3-beta
|
|
24
|
+
|
|
25
|
+
## 0.18.3-beta
|
|
26
|
+
|
|
27
|
+
### Patch Changes
|
|
28
|
+
|
|
29
|
+
- Pin core to the tested release.
|
|
30
|
+
- Pin agents to the tested release.
|
|
31
|
+
- Pin admin to the tested release.
|
|
32
|
+
- Pin runtime to the tested release.
|
|
33
|
+
- Pin studio to the tested release.
|
|
34
|
+
- Updated dependencies [fce0c9b]
|
|
35
|
+
- Updated dependencies [ab7c08a]
|
|
36
|
+
- Updated dependencies [4a563e7]
|
|
37
|
+
- Updated dependencies
|
|
38
|
+
- Updated dependencies
|
|
39
|
+
- @nylorun/core@0.26.0-beta
|
|
40
|
+
- @nylorun/agents@0.26.0-beta
|
|
41
|
+
- @nylorun/admin@0.19.2-beta
|
|
42
|
+
|
|
3
43
|
## 0.18.2-beta
|
|
4
44
|
|
|
5
45
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -53,7 +53,9 @@ 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
|
|
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
|
|
57
59
|
nylorun migrate v8 <agent.json> [--runtime <environment-manifest.json>] [--name <name>] [--out <dir>] # the three files from a v7 manifest; reads no Runtime
|
|
58
60
|
nylorun agent-manifests list [--json] # name, latest version, runtime kind, harness, Agents
|
|
59
61
|
nylorun agent-manifests get <name>[@<n>] | versions <name> | rm <name>
|
|
@@ -476,7 +478,25 @@ from a terminal.
|
|
|
476
478
|
An agent runs from a saved **agent manifest** (protocol 16): one named, versioned
|
|
477
479
|
document with a harness section (instructions, tools, skills, MCP servers,
|
|
478
480
|
plugins) and a runtime section (kind, image, network, setup, files, secret
|
|
479
|
-
slots). Author it as
|
|
481
|
+
slots). Author it as an agent folder (track T6), one folder per agent:
|
|
482
|
+
|
|
483
|
+
```
|
|
484
|
+
agents/support/AGENT.md # frontmatter (name, description), then the instructions
|
|
485
|
+
agents/support/mcp.json # MCP servers; "Authorization": "Bearer ${GITHUB_TOKEN}" names a slot
|
|
486
|
+
agents/support/runtime.json # kind, network, secrets (optional)
|
|
487
|
+
agents/support/skills/<skill>/SKILL.md, tools/<tool>.json, triggers/<id>.md, files/**
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
`nylorun init support` writes the `AGENT.md`; `nylorun check agents/support`
|
|
491
|
+
compiles the folder offline with the Runtime's compiler and prints every problem
|
|
492
|
+
as `file:line:column severity: message`, exiting 1 when it does not compile.
|
|
493
|
+
`nylorun apply agents/support` checks it the same way (sending nothing when it
|
|
494
|
+
does not compile), plans it, prints the compiler's notes (such as a slot derived
|
|
495
|
+
from `mcp.json`) and saves it, uploading its files by hash; the Runtime keeps the
|
|
496
|
+
folder as the version's source. `--dry-run` also prints the compiled manifest. A
|
|
497
|
+
change only to a file outside the agent, such as a README, is `unchanged`.
|
|
498
|
+
|
|
499
|
+
Or as three files:
|
|
480
500
|
|
|
481
501
|
```
|
|
482
502
|
agents/triage/agent.manifest.json # { "manifestSchemaVersion": 8, "name": "triage",
|
package/dist/cli.js
CHANGED
|
@@ -13,9 +13,12 @@ ${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)
|
|
16
19
|
apply [<dir>...] [--dry-run] [--if-match <n>]
|
|
17
|
-
save the agent manifest each folder
|
|
18
|
-
|
|
20
|
+
save the agent manifest each folder describes (its AGENT.md,
|
|
21
|
+
or its agent.manifest.json), with its files (Runtime API)
|
|
19
22
|
migrate v8 <agent.json> [--runtime <environment-manifest.json>] [--name <name>] [--out <dir>]
|
|
20
23
|
write the three manifest files from an agent manifest v7
|
|
21
24
|
and an environment manifest v1 (reads no Runtime)
|
|
@@ -164,6 +167,8 @@ async function main() {
|
|
|
164
167
|
return;
|
|
165
168
|
}
|
|
166
169
|
if (command === "apply" ||
|
|
170
|
+
command === "check" ||
|
|
171
|
+
command === "init" ||
|
|
167
172
|
command === "migrate" ||
|
|
168
173
|
command === "agent-manifests" ||
|
|
169
174
|
command === "agents" ||
|
|
@@ -171,6 +176,8 @@ async function main() {
|
|
|
171
176
|
command === "artifacts") {
|
|
172
177
|
const group = {
|
|
173
178
|
apply: async () => (await import("./client/apply.js")).applyCommand,
|
|
179
|
+
check: async () => (await import("./client/folder.js")).checkCommand,
|
|
180
|
+
init: async () => (await import("./client/folder.js")).initCommand,
|
|
174
181
|
migrate: async () => (await import("./client/migrate.js")).migrateCommand,
|
|
175
182
|
"agent-manifests": async () => (await import("./client/agent-manifests.js")).agentManifestsCommand,
|
|
176
183
|
agents: async () => (await import("./client/agents.js")).agentsCommand,
|
package/dist/client/apply.js
CHANGED
|
@@ -7,24 +7,33 @@
|
|
|
7
7
|
* version the plan was made against, so a save that raced another fails (`412 manifest_changed`)
|
|
8
8
|
* instead of overwriting it. A folder without an `agent.manifest.json` applies each subfolder
|
|
9
9
|
* that has one (`nylorun apply agents/`).
|
|
10
|
+
*
|
|
11
|
+
* An agent folder (a folder with `AGENT.md`, track T6) is compiled offline first, and one that does
|
|
12
|
+
* not compile sends nothing; otherwise its files go up by hash and the Runtime compiles it again
|
|
13
|
+
* and keeps it as the version's source. Its plan adds the compiler's notes, and `--dry-run` prints
|
|
14
|
+
* the compiled manifest.
|
|
10
15
|
*/
|
|
11
16
|
import { resolve } from "node:path";
|
|
12
|
-
import { ComposeError, PluginError, SkillsError, composeManifest, manifestFolders, } from "@nylorun/agents";
|
|
17
|
+
import { ComposeError, PluginError, SkillsError, checkFolder, composeManifest, isAgentFolder, manifestFolders, } from "@nylorun/agents";
|
|
13
18
|
import { CliError } from "../errors.js";
|
|
19
|
+
import { agentFolders, diagnosticLines, packed } from "./folder.js";
|
|
14
20
|
import { integerFlag, parseFlags, runtimeCall, runtimeClient, runtimeFlagsUsage, usageError } from "./runtime.js";
|
|
15
21
|
export const applyUsage = `nylorun apply [<dir>...] [--dry-run] [--if-match <n>]
|
|
16
22
|
|
|
17
23
|
Saves the agent manifest each folder describes (default .), through the Runtime API with an
|
|
18
|
-
application key (or NYLORUN_TOKEN).
|
|
19
|
-
|
|
20
|
-
|
|
24
|
+
application key (or NYLORUN_TOKEN). An agent folder holds AGENT.md (nylorun init): it is checked
|
|
25
|
+
offline as nylorun check does, sent by hash, and kept as the version's source. A folder may hold
|
|
26
|
+
agent.manifest.json instead, which names its harness.manifest.json and runtime.manifest.json
|
|
27
|
+
(paths relative to the file that names them). A folder with neither applies each subfolder that
|
|
28
|
+
has one.
|
|
21
29
|
|
|
22
30
|
Each manifest is planned first: the version it moves from and to, each change (section, path,
|
|
23
31
|
op), warnings and errors. With no errors it is saved, its skills', plugins' and runtime files
|
|
24
32
|
uploaded first, under If-Match set to the version planned against (0 for a new manifest).
|
|
25
33
|
Errors, the gaps between its sections included, save nothing and exit 1.
|
|
26
34
|
|
|
27
|
-
--dry-run print the plans and
|
|
35
|
+
--dry-run print the plans, and an agent folder's compiled manifest, and
|
|
36
|
+
save nothing
|
|
28
37
|
--if-match <n> save only over version n (one folder)
|
|
29
38
|
|
|
30
39
|
${runtimeFlagsUsage}`;
|
|
@@ -48,6 +57,13 @@ export function planLines(plan) {
|
|
|
48
57
|
...plan.errors.map((error) => ` error: ${error}`),
|
|
49
58
|
];
|
|
50
59
|
}
|
|
60
|
+
function reportSaved(deps, saved, label) {
|
|
61
|
+
deps.err(saved.unchanged
|
|
62
|
+
? `Agent manifest ${saved.manifest.name} is unchanged at version ${saved.manifest.version} on ${label}.`
|
|
63
|
+
: `Saved agent manifest ${saved.manifest.name} version ${saved.manifest.version} on ${label}.`);
|
|
64
|
+
for (const warning of saved.warnings)
|
|
65
|
+
deps.err(` warning: ${warning.message}`);
|
|
66
|
+
}
|
|
51
67
|
/** `nylorun apply [dir…] [--dry-run] [--if-match <n>]` */
|
|
52
68
|
export async function applyCommand(deps, args) {
|
|
53
69
|
if (args[0] === "--help" || args[0] === "-h") {
|
|
@@ -60,38 +76,79 @@ export async function applyCommand(deps, args) {
|
|
|
60
76
|
const cwd = deps.cwd ?? process.cwd();
|
|
61
77
|
const folders = [];
|
|
62
78
|
for (const dir of flags.rest.length > 0 ? flags.rest : ["."]) {
|
|
63
|
-
const
|
|
79
|
+
const at = resolve(cwd, dir);
|
|
80
|
+
const found = (await isAgentFolder(at))
|
|
81
|
+
? [at]
|
|
82
|
+
: [
|
|
83
|
+
...new Set([
|
|
84
|
+
...(await manifestFolders(at).catch((error) => composeFailure(dir, error))),
|
|
85
|
+
...(await agentFolders(at)),
|
|
86
|
+
]),
|
|
87
|
+
].sort();
|
|
64
88
|
if (found.length === 0)
|
|
65
|
-
throw usageError(`${dir} holds no agent.manifest.json, and no subfolder does.`);
|
|
89
|
+
throw usageError(`${dir} holds no AGENT.md or agent.manifest.json, and no subfolder does.`);
|
|
66
90
|
folders.push(...found);
|
|
67
91
|
}
|
|
68
92
|
if (ifMatch !== undefined && folders.length > 1)
|
|
69
93
|
throw usageError("--if-match takes one manifest: name one folder.");
|
|
70
|
-
// Every folder composes before anything is sent: a broken file stops the whole apply.
|
|
71
|
-
const
|
|
72
|
-
for (const folder of folders)
|
|
73
|
-
composed.push({ folder, manifest: await composeManifest(folder).catch((error) => composeFailure(folder, error)) });
|
|
74
|
-
const { client, connection } = await runtimeClient(deps, flags);
|
|
94
|
+
// Every folder composes, or compiles, before anything is sent: a broken file stops the whole apply.
|
|
95
|
+
const work = [];
|
|
75
96
|
let blocked = false;
|
|
76
|
-
for (const
|
|
97
|
+
for (const folder of folders) {
|
|
98
|
+
if (await isAgentFolder(folder)) {
|
|
99
|
+
const pack = await packed(folder);
|
|
100
|
+
const compiled = await checkFolder(pack);
|
|
101
|
+
if (!compiled.manifest) {
|
|
102
|
+
for (const line of diagnosticLines(folder, cwd, compiled.diagnostics))
|
|
103
|
+
deps.err(line);
|
|
104
|
+
blocked = true;
|
|
105
|
+
}
|
|
106
|
+
work.push({ folder, pack });
|
|
107
|
+
}
|
|
108
|
+
else
|
|
109
|
+
work.push({ folder, manifest: await composeManifest(folder).catch((error) => composeFailure(folder, error)) });
|
|
110
|
+
}
|
|
111
|
+
if (blocked) {
|
|
112
|
+
deps.err("Nothing was sent: an agent folder does not compile (nylorun check).");
|
|
113
|
+
return 1;
|
|
114
|
+
}
|
|
115
|
+
const { client, connection } = await runtimeClient(deps, flags);
|
|
116
|
+
const dryRun = flags.booleans.has("--dry-run");
|
|
117
|
+
for (const item of work) {
|
|
118
|
+
const options = ifMatch === undefined ? {} : { ifMatch };
|
|
119
|
+
if ("pack" in item) {
|
|
120
|
+
const plan = await runtimeCall(() => client.agentManifests.planFolder(item.pack, options));
|
|
121
|
+
for (const line of planLines(plan))
|
|
122
|
+
deps.out(line);
|
|
123
|
+
for (const line of diagnosticLines(item.folder, cwd, (plan.diagnostics ?? []).filter((d) => d.severity !== "error")))
|
|
124
|
+
deps.out(` ${line}`);
|
|
125
|
+
if (dryRun && plan.manifest)
|
|
126
|
+
deps.out(JSON.stringify(plan.manifest, null, 2));
|
|
127
|
+
if (plan.errors.length > 0) {
|
|
128
|
+
blocked = true;
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
if (dryRun || plan.unchanged)
|
|
132
|
+
continue;
|
|
133
|
+
const saved = await runtimeCall(() => client.agentManifests.saveFolder(item.pack, { ifMatch: ifMatch ?? plan.from ?? 0 }));
|
|
134
|
+
reportSaved(deps, saved, connection.label);
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
const { manifest } = item;
|
|
77
138
|
for (const warning of manifest.warnings)
|
|
78
139
|
deps.err(`${manifest.manifest.name}: warning: ${warning}`);
|
|
79
140
|
// The plan's errors include the gaps the composer found (its sections, the harness's requires).
|
|
80
|
-
const plan = await runtimeCall(() => client.agentManifests.plan(manifest,
|
|
141
|
+
const plan = await runtimeCall(() => client.agentManifests.plan(manifest, options));
|
|
81
142
|
for (const line of planLines(plan))
|
|
82
143
|
deps.out(line);
|
|
83
144
|
if (plan.errors.length > 0) {
|
|
84
145
|
blocked = true;
|
|
85
146
|
continue;
|
|
86
147
|
}
|
|
87
|
-
if (
|
|
148
|
+
if (dryRun || plan.unchanged)
|
|
88
149
|
continue;
|
|
89
150
|
const saved = await runtimeCall(() => client.agentManifests.save(manifest, { ifMatch: ifMatch ?? plan.from ?? 0 }));
|
|
90
|
-
deps
|
|
91
|
-
? `Agent manifest ${saved.manifest.name} is unchanged at version ${saved.manifest.version} on ${connection.label}.`
|
|
92
|
-
: `Saved agent manifest ${saved.manifest.name} version ${saved.manifest.version} on ${connection.label}.`);
|
|
93
|
-
for (const warning of saved.warnings)
|
|
94
|
-
deps.err(` warning: ${warning.message}`);
|
|
151
|
+
reportSaved(deps, saved, connection.label);
|
|
95
152
|
}
|
|
96
153
|
if (blocked)
|
|
97
154
|
deps.err("Nothing was saved for a manifest with errors.");
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type PackedFolder } from "@nylorun/agents";
|
|
2
|
+
import type { AgentFolderDiagnostic } from "@nylorun/core/folder";
|
|
3
|
+
import { type StackDeps } from "../stack/commands.js";
|
|
4
|
+
export declare const checkUsage = "nylorun check [<dir>...]\n\nCompiles each agent folder (default .) offline, with the compiler the Runtime runs, and prints\nevery problem by file, line and column. A folder holds AGENT.md; a folder without one checks each\nsubfolder that has one. Exits 1 when a folder does not compile. Reads no Runtime.";
|
|
5
|
+
export declare const initUsage = "nylorun init <name> [--description <text>]\n\nWrites <name>/AGENT.md, the smallest agent folder: frontmatter with its name and description, and\nits instructions below. Save it with nylorun apply <name>.";
|
|
6
|
+
/** The agent folders under `dir`: `dir` when it holds an `AGENT.md`, else each subfolder that does. */
|
|
7
|
+
export declare function agentFolders(dir: string): Promise<string[]>;
|
|
8
|
+
/** Packs the folder, or a `CliError` naming why it cannot be. */
|
|
9
|
+
export declare function packed(folder: string): Promise<PackedFolder>;
|
|
10
|
+
/** A folder's diagnostics as lines, each path relative to `cwd`. */
|
|
11
|
+
export declare function diagnosticLines(folder: string, cwd: string, diagnostics: readonly AgentFolderDiagnostic[]): string[];
|
|
12
|
+
/** `nylorun check [dir…]` */
|
|
13
|
+
export declare function checkCommand(deps: StackDeps, args: readonly string[]): Promise<number>;
|
|
14
|
+
/** `nylorun init <name> [--description <text>]` */
|
|
15
|
+
export declare function initCommand(deps: StackDeps, args: readonly string[]): Promise<number>;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent folders (track T6, D79) on the command line, offline: `nylorun check [dir…]` compiles each
|
|
3
|
+
* agent folder with the compiler the Runtime runs (`@nylorun/core/folder`) and prints every
|
|
4
|
+
* diagnostic by file, line and column; `nylorun init <name>` writes a new folder's `AGENT.md`.
|
|
5
|
+
* Neither reads a Runtime. `nylorun apply` saves a folder (`apply.ts`).
|
|
6
|
+
*/
|
|
7
|
+
import { existsSync } from "node:fs";
|
|
8
|
+
import { mkdir, readdir, writeFile } from "node:fs/promises";
|
|
9
|
+
import { basename, join, relative, resolve } from "node:path";
|
|
10
|
+
import { isAgentManifestName } from "@nylorun/core/contracts";
|
|
11
|
+
import { AGENT_FOLDER_FILE, FolderError, checkFolder, diagnosticLine, isAgentFolder, packFolder, } from "@nylorun/agents";
|
|
12
|
+
import { CliError } from "../errors.js";
|
|
13
|
+
import { parseStackFlags } from "../stack/commands.js";
|
|
14
|
+
import { usageError } from "./runtime.js";
|
|
15
|
+
export const checkUsage = `nylorun check [<dir>...]
|
|
16
|
+
|
|
17
|
+
Compiles each agent folder (default .) offline, with the compiler the Runtime runs, and prints
|
|
18
|
+
every problem by file, line and column. A folder holds AGENT.md; a folder without one checks each
|
|
19
|
+
subfolder that has one. Exits 1 when a folder does not compile. Reads no Runtime.`;
|
|
20
|
+
export const initUsage = `nylorun init <name> [--description <text>]
|
|
21
|
+
|
|
22
|
+
Writes <name>/AGENT.md, the smallest agent folder: frontmatter with its name and description, and
|
|
23
|
+
its instructions below. Save it with nylorun apply <name>.`;
|
|
24
|
+
/** The agent folders under `dir`: `dir` when it holds an `AGENT.md`, else each subfolder that does. */
|
|
25
|
+
export async function agentFolders(dir) {
|
|
26
|
+
const root = resolve(dir);
|
|
27
|
+
if (await isAgentFolder(root))
|
|
28
|
+
return [root];
|
|
29
|
+
const entries = await readdir(root, { withFileTypes: true }).catch(() => []);
|
|
30
|
+
const found = [];
|
|
31
|
+
for (const entry of entries.filter((item) => item.isDirectory()).sort((a, b) => (a.name < b.name ? -1 : 1)))
|
|
32
|
+
if (await isAgentFolder(join(root, entry.name)))
|
|
33
|
+
found.push(join(root, entry.name));
|
|
34
|
+
return found;
|
|
35
|
+
}
|
|
36
|
+
/** Packs the folder, or a `CliError` naming why it cannot be. */
|
|
37
|
+
export async function packed(folder) {
|
|
38
|
+
return packFolder(folder).catch((error) => {
|
|
39
|
+
if (error instanceof FolderError)
|
|
40
|
+
throw new CliError(error.message, 1);
|
|
41
|
+
throw error;
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/** A folder's diagnostics as lines, each path relative to `cwd`. */
|
|
45
|
+
export function diagnosticLines(folder, cwd, diagnostics) {
|
|
46
|
+
const prefix = relative(cwd, folder);
|
|
47
|
+
return diagnostics.map((item) => diagnosticLine(item.file && prefix ? { ...item, file: `${prefix}/${item.file}` } : item));
|
|
48
|
+
}
|
|
49
|
+
/** `nylorun check [dir…]` */
|
|
50
|
+
export async function checkCommand(deps, args) {
|
|
51
|
+
const flags = parseStackFlags(args, {}, checkUsage);
|
|
52
|
+
const cwd = deps.cwd ?? process.cwd();
|
|
53
|
+
const folders = [];
|
|
54
|
+
for (const dir of flags.rest.length > 0 ? flags.rest : ["."]) {
|
|
55
|
+
const found = await agentFolders(resolve(cwd, dir));
|
|
56
|
+
if (found.length === 0)
|
|
57
|
+
throw usageError(`${dir} holds no ${AGENT_FOLDER_FILE}, and no subfolder does.`);
|
|
58
|
+
folders.push(...found);
|
|
59
|
+
}
|
|
60
|
+
let failed = false;
|
|
61
|
+
for (const folder of folders) {
|
|
62
|
+
const pack = await packed(folder);
|
|
63
|
+
const compiled = await checkFolder(pack);
|
|
64
|
+
for (const skipped of pack.skipped)
|
|
65
|
+
deps.err(`${relative(cwd, folder) || "."}: skipped ${skipped}`);
|
|
66
|
+
for (const line of diagnosticLines(folder, cwd, compiled.diagnostics))
|
|
67
|
+
if (compiled.manifest)
|
|
68
|
+
deps.out(line);
|
|
69
|
+
else
|
|
70
|
+
deps.err(line);
|
|
71
|
+
const label = relative(cwd, folder) || basename(folder);
|
|
72
|
+
if (compiled.manifest)
|
|
73
|
+
deps.out(`${label}: ok, agent manifest ${compiled.manifest.name} (${pack.entries.length} files, ${compiled.compiler})`);
|
|
74
|
+
else {
|
|
75
|
+
failed = true;
|
|
76
|
+
const errors = compiled.diagnostics.filter((item) => item.severity === "error").length;
|
|
77
|
+
deps.err(`${label}: ${errors} ${errors === 1 ? "error" : "errors"}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return failed ? 1 : 0;
|
|
81
|
+
}
|
|
82
|
+
/** `nylorun init <name> [--description <text>]` */
|
|
83
|
+
export async function initCommand(deps, args) {
|
|
84
|
+
const flags = parseStackFlags(args, { values: ["--description"] }, initUsage);
|
|
85
|
+
const [name, ...rest] = flags.rest;
|
|
86
|
+
if (name === undefined || rest.length > 0)
|
|
87
|
+
throw usageError(`Usage: ${initUsage.split("\n")[0]}`);
|
|
88
|
+
if (!isAgentManifestName(name))
|
|
89
|
+
throw usageError(`${name} is not an agent's name: 1-64 letters, digits, '.', '_' and '-', starting with a letter or digit.`);
|
|
90
|
+
const dir = resolve(deps.cwd ?? process.cwd(), name);
|
|
91
|
+
const file = join(dir, AGENT_FOLDER_FILE);
|
|
92
|
+
if (existsSync(file))
|
|
93
|
+
throw new CliError(`${relative(deps.cwd ?? process.cwd(), file)} exists already.`, 1);
|
|
94
|
+
const description = flags.values.get("--description") ?? `Describe what ${name} does in one sentence.`;
|
|
95
|
+
await mkdir(dir, { recursive: true });
|
|
96
|
+
await writeFile(file, `---\nname: ${name}\ndescription: ${JSON.stringify(description)}\n---\nYou are ${name}. Write the agent's instructions here, in Markdown.\n`, { flag: "wx" });
|
|
97
|
+
deps.out(`Wrote ${relative(deps.cwd ?? process.cwd(), file)}. Check it with nylorun check ${name}, and save it with nylorun apply ${name}.`);
|
|
98
|
+
return 0;
|
|
99
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nylorun",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.0-beta",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"description": "Set up and run local Nylorun Tenants (Runtime and Studio) with Docker Compose, and act on a Tenant through its Runtime and Management APIs",
|
|
@@ -30,9 +30,9 @@
|
|
|
30
30
|
"prepack": "npm run build"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@nylorun/admin": "0.19.
|
|
34
|
-
"@nylorun/agents": "0.
|
|
35
|
-
"@nylorun/core": "0.
|
|
33
|
+
"@nylorun/admin": "0.19.3-beta",
|
|
34
|
+
"@nylorun/agents": "0.27.0-beta",
|
|
35
|
+
"@nylorun/core": "0.27.0-beta"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@earendil-works/pi-ai": "1.2.0",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"nylo": "dist/nylo.js"
|
|
47
47
|
},
|
|
48
48
|
"nylorun": {
|
|
49
|
-
"runtime": "0.
|
|
50
|
-
"studio": "0.
|
|
49
|
+
"runtime": "0.31.0-beta",
|
|
50
|
+
"studio": "0.31.1-beta"
|
|
51
51
|
}
|
|
52
52
|
}
|