@zenera/cli 1.1.19 → 1.1.21
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/README.md +6 -0
- package/dist/banner.d.ts +20 -0
- package/dist/banner.js +10 -0
- package/dist/commands/cache.js +1 -0
- package/dist/commands/check.js +34 -2
- package/dist/commands/index.js +1 -1
- package/dist/commands/init.js +1 -1
- package/dist/commands/meta.js +1 -1
- package/dist/commands/models.js +1 -0
- package/dist/commands/open.js +1 -1
- package/dist/lib.d.ts +1 -1
- package/dist/lib.js +1 -1
- package/dist/main.js +8 -1
- package/dist/meta.js +19 -7
- package/dist/scaffold.d.ts +37 -0
- package/dist/scaffold.js +67 -3
- package/dist/term.d.ts +2 -0
- package/dist/term.js +25 -0
- package/dist/tui/app.js +237 -65
- package/dist/tui/theme.d.ts +10 -0
- package/dist/tui/theme.js +4 -0
- package/dist/tui/wrap.d.ts +100 -18
- package/dist/tui/wrap.js +500 -27
- package/dist/validate.js +115 -9
- package/package.json +2 -2
- package/templates/editor/.github/copilot-instructions.md +33 -8
- package/templates/editor/.github/skills/zen-cli/references/projects.md +19 -8
- package/templates/editor/.github/skills/zen-memory/SKILL.md +77 -33
- package/templates/editor/.github/skills/zen-memory/scripts/check-instructions.sh +2 -1
- package/templates/editor/.vscode/agents.schema.json +611 -0
- package/templates/editor/.vscode/extensions.json +3 -0
- package/templates/editor/.vscode/settings.json +8 -0
- package/templates/project/agents/fork-instructions.md +151 -0
- package/templates/project/agents/memory-instructions.md +120 -8
|
@@ -0,0 +1,611 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://raw.githubusercontent.com/andreyryabov/ZeneraNeo/main/packages/cli/templates/editor/.vscode/agents.schema.json",
|
|
4
|
+
"title": "Zenera Neo agents.yaml",
|
|
5
|
+
"description": "Who exists in this project, what they may reach for, and which model answers for them. Written by `zen init` and replaced by every `zen init` and `zen open`, so it describes the version of `zen` in hand. The runtime is the authority: `zen check` reads the project the way a run does.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": ["agents"],
|
|
8
|
+
"additionalProperties": false,
|
|
9
|
+
"properties": {
|
|
10
|
+
"version": {
|
|
11
|
+
"description": "Schema version. There is one.",
|
|
12
|
+
"const": 1,
|
|
13
|
+
"default": 1
|
|
14
|
+
},
|
|
15
|
+
"default": {
|
|
16
|
+
"description": "The agent a run starts at. Wins over any agent's `default: true`.",
|
|
17
|
+
"$ref": "#/$defs/name"
|
|
18
|
+
},
|
|
19
|
+
"providers": {
|
|
20
|
+
"description": "Named connections: where requests go, and what credentials sign them. Declaring one is what lets a project hold two keys for the same vendor — the key is named once here, and models point at the name. The built-in kinds work without being declared.",
|
|
21
|
+
"type": "object",
|
|
22
|
+
"propertyNames": { "$ref": "#/$defs/name" },
|
|
23
|
+
"additionalProperties": { "$ref": "#/$defs/provider" }
|
|
24
|
+
},
|
|
25
|
+
"provider": {
|
|
26
|
+
"description": "The provider a bare model id belongs to, when the id carries no `<provider>:` prefix. Defaults to `openai`.",
|
|
27
|
+
"$ref": "#/$defs/name"
|
|
28
|
+
},
|
|
29
|
+
"models": {
|
|
30
|
+
"description": "Named model configurations, referred to by `model:` anywhere below. A name is either a shorthand reference or the object form, which is what gives reasoning and token knobs somewhere to live.",
|
|
31
|
+
"type": "object",
|
|
32
|
+
"propertyNames": { "$ref": "#/$defs/name" },
|
|
33
|
+
"additionalProperties": {
|
|
34
|
+
"oneOf": [{ "$ref": "#/$defs/modelRef" }, { "$ref": "#/$defs/modelSpec" }]
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"model": {
|
|
38
|
+
"description": "The model an agent uses when it does not pin its own. Change it here and the whole project moves.",
|
|
39
|
+
"$ref": "#/$defs/modelRef"
|
|
40
|
+
},
|
|
41
|
+
"embeddings": {
|
|
42
|
+
"description": "Named vectorisers, referred to by `embedding:` here and under `memory:`.",
|
|
43
|
+
"type": "object",
|
|
44
|
+
"propertyNames": { "$ref": "#/$defs/name" },
|
|
45
|
+
"additionalProperties": {
|
|
46
|
+
"oneOf": [{ "$ref": "#/$defs/modelRef" }, { "$ref": "#/$defs/embeddingSpec" }]
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"embedding": {
|
|
50
|
+
"description": "The vectoriser handed back when one is asked for by no name.",
|
|
51
|
+
"$ref": "#/$defs/modelRef"
|
|
52
|
+
},
|
|
53
|
+
"skills": {
|
|
54
|
+
"description": "Skill directories, relative to the project root, merged into one catalog. `agents/skills` by convention, so this is only for a catalog kept somewhere else or shared between projects.",
|
|
55
|
+
"oneOf": [
|
|
56
|
+
{ "type": "string", "minLength": 1 },
|
|
57
|
+
{ "type": "array", "items": { "type": "string", "minLength": 1 } }
|
|
58
|
+
]
|
|
59
|
+
},
|
|
60
|
+
"assets": {
|
|
61
|
+
"description": "Reference material, mounted read-only at /assets for every agent. `assets/` by convention, so this is only for material kept elsewhere in the project.",
|
|
62
|
+
"type": "string",
|
|
63
|
+
"minLength": 1,
|
|
64
|
+
"default": "assets"
|
|
65
|
+
},
|
|
66
|
+
"sandbox": {
|
|
67
|
+
"description": "The container `run_command` and the other shell tools execute in.",
|
|
68
|
+
"$ref": "#/$defs/sandbox"
|
|
69
|
+
},
|
|
70
|
+
"memory": {
|
|
71
|
+
"description": "The one graph every agent's `memory:` binding is a view onto. An agent that opts in without this block gets the defaults; a project that mentions memory nowhere opens no store at all.",
|
|
72
|
+
"$ref": "#/$defs/memoryConfig"
|
|
73
|
+
},
|
|
74
|
+
"agents": {
|
|
75
|
+
"description": "At least one. The first is the entry point unless `default:` says otherwise.",
|
|
76
|
+
"type": "array",
|
|
77
|
+
"minItems": 1,
|
|
78
|
+
"items": { "$ref": "#/$defs/agent" }
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
"$defs": {
|
|
82
|
+
"name": {
|
|
83
|
+
"description": "Lower-case words joined by `-` or `_`. Names reach the model as part of `transfer_to_<name>` and reach the file system as directory names, so they are unambiguous in both.",
|
|
84
|
+
"type": "string",
|
|
85
|
+
"pattern": "^[a-z0-9]+(?:[-_][a-z0-9]+)*$"
|
|
86
|
+
},
|
|
87
|
+
"modelRef": {
|
|
88
|
+
"description": "A key into `models:`, or the shorthand — `gpt-4o`, `openai:o3`, `openai/responses:o3`, `openrouter:anthropic/claude-sonnet-4.5`. The prefix is the provider name, not the vendor.",
|
|
89
|
+
"type": "string",
|
|
90
|
+
"minLength": 1
|
|
91
|
+
},
|
|
92
|
+
"apiKey": {
|
|
93
|
+
"description": "The key itself, or `${VAR}`. Wins over any environment lookup. Substitution happens when the model is built, so a configuration nothing uses never demands a key.",
|
|
94
|
+
"type": "string",
|
|
95
|
+
"minLength": 1
|
|
96
|
+
},
|
|
97
|
+
"apiKeyEnv": {
|
|
98
|
+
"description": "The environment variable holding the key. Defaults to the kind's conventional name — `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `GEMINI_API_KEY`, `OPENROUTER_API_KEY`.",
|
|
99
|
+
"type": "string",
|
|
100
|
+
"minLength": 1
|
|
101
|
+
},
|
|
102
|
+
"baseURL": {
|
|
103
|
+
"description": "The endpoint, or `${VAR}` — for gateways and compatible endpoints.",
|
|
104
|
+
"type": "string",
|
|
105
|
+
"minLength": 1
|
|
106
|
+
},
|
|
107
|
+
"baseURLEnv": {
|
|
108
|
+
"description": "The environment variable holding the base url.",
|
|
109
|
+
"type": "string",
|
|
110
|
+
"minLength": 1
|
|
111
|
+
},
|
|
112
|
+
"provider": {
|
|
113
|
+
"description": "A connection, not a model. One client is built per name and shared, so five agents on one key open one connection pool.",
|
|
114
|
+
"type": "object",
|
|
115
|
+
"additionalProperties": false,
|
|
116
|
+
"properties": {
|
|
117
|
+
"kind": {
|
|
118
|
+
"description": "Which protocol, and so which SDK and adapter. Each vendor's own SDK is used rather than its OpenAI-compatible endpoint, which drops thinking budgets and cache accounting. `openai-compatible` is the shim — vLLM, a self-hosted gateway. Defaults to `openai`.",
|
|
119
|
+
"type": "string",
|
|
120
|
+
"enum": [
|
|
121
|
+
"openai",
|
|
122
|
+
"google",
|
|
123
|
+
"vertex",
|
|
124
|
+
"anthropic",
|
|
125
|
+
"openrouter",
|
|
126
|
+
"openai-compatible"
|
|
127
|
+
],
|
|
128
|
+
"default": "openai"
|
|
129
|
+
},
|
|
130
|
+
"apiKey": { "$ref": "#/$defs/apiKey" },
|
|
131
|
+
"apiKeyEnv": { "$ref": "#/$defs/apiKeyEnv" },
|
|
132
|
+
"baseURL": { "$ref": "#/$defs/baseURL" },
|
|
133
|
+
"baseURLEnv": { "$ref": "#/$defs/baseURLEnv" },
|
|
134
|
+
"project": {
|
|
135
|
+
"description": "vertex only — the GCP project id the endpoint is addressed by.",
|
|
136
|
+
"type": "string",
|
|
137
|
+
"minLength": 1
|
|
138
|
+
},
|
|
139
|
+
"location": {
|
|
140
|
+
"description": "vertex only — a region, or `global`.",
|
|
141
|
+
"type": "string",
|
|
142
|
+
"minLength": 1
|
|
143
|
+
},
|
|
144
|
+
"headers": {
|
|
145
|
+
"description": "Sent on every request: gateway routing, attribution, api versions.",
|
|
146
|
+
"type": "object",
|
|
147
|
+
"propertyNames": { "type": "string", "minLength": 1 },
|
|
148
|
+
"additionalProperties": { "type": "string" }
|
|
149
|
+
},
|
|
150
|
+
"timeoutMs": {
|
|
151
|
+
"description": "Per-request timeout, in milliseconds.",
|
|
152
|
+
"type": "number",
|
|
153
|
+
"exclusiveMinimum": 0
|
|
154
|
+
},
|
|
155
|
+
"maxRetries": {
|
|
156
|
+
"description": "Extra attempts on a 429, a 408 or a 5xx, waiting 1s then 2s, 4s, 8s — doubling up to a minute, and honouring `Retry-After`. Retrying happens at the transport, so a retried call is one that never started. `0` fails fast.",
|
|
157
|
+
"type": "integer",
|
|
158
|
+
"minimum": 0,
|
|
159
|
+
"default": 4
|
|
160
|
+
},
|
|
161
|
+
"concurrency": {
|
|
162
|
+
"description": "Ceiling on embedding requests in flight on this connection. The working number is discovered from the provider's own refusals; this only caps how high it may climb, for a key something else also needs quota from.",
|
|
163
|
+
"type": "integer",
|
|
164
|
+
"exclusiveMinimum": 0
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
"routing": {
|
|
169
|
+
"description": "openrouter only — which upstream provider serves a request. Named `routing` because `provider:` here already means the connection.",
|
|
170
|
+
"type": "object",
|
|
171
|
+
"additionalProperties": false,
|
|
172
|
+
"properties": {
|
|
173
|
+
"order": {
|
|
174
|
+
"description": "Providers to try first. A preference, not a restriction.",
|
|
175
|
+
"type": "array",
|
|
176
|
+
"minItems": 1,
|
|
177
|
+
"items": { "type": "string", "minLength": 1 }
|
|
178
|
+
},
|
|
179
|
+
"only": {
|
|
180
|
+
"description": "Restricts serving to these, rather than merely preferring them.",
|
|
181
|
+
"type": "array",
|
|
182
|
+
"minItems": 1,
|
|
183
|
+
"items": { "type": "string", "minLength": 1 }
|
|
184
|
+
},
|
|
185
|
+
"ignore": {
|
|
186
|
+
"description": "Providers that may never serve this request.",
|
|
187
|
+
"type": "array",
|
|
188
|
+
"minItems": 1,
|
|
189
|
+
"items": { "type": "string", "minLength": 1 }
|
|
190
|
+
},
|
|
191
|
+
"sort": {
|
|
192
|
+
"description": "`price`, `throughput`, `latency`, `exacto`. A plain string because OpenRouter adds to the set continuously.",
|
|
193
|
+
"type": "string",
|
|
194
|
+
"minLength": 1
|
|
195
|
+
},
|
|
196
|
+
"allowFallbacks": {
|
|
197
|
+
"description": "May OpenRouter go beyond `order`. On unless set false.",
|
|
198
|
+
"type": "boolean",
|
|
199
|
+
"default": true
|
|
200
|
+
},
|
|
201
|
+
"requireParameters": {
|
|
202
|
+
"description": "Skip a provider that would silently drop a parameter rather than serve it.",
|
|
203
|
+
"type": "boolean"
|
|
204
|
+
},
|
|
205
|
+
"dataCollection": {
|
|
206
|
+
"description": "Whether a provider that trains on requests may serve this one.",
|
|
207
|
+
"type": "string",
|
|
208
|
+
"enum": ["allow", "deny"]
|
|
209
|
+
},
|
|
210
|
+
"quantizations": {
|
|
211
|
+
"description": "`int4` `int8` `fp4` `mxfp4` `nvfp4` `fp6` `fp8` `mxfp8` `fp16` `bf16` `fp32`.",
|
|
212
|
+
"type": "array",
|
|
213
|
+
"minItems": 1,
|
|
214
|
+
"items": { "type": "string", "minLength": 1 }
|
|
215
|
+
},
|
|
216
|
+
"zdr": {
|
|
217
|
+
"description": "Zero-data-retention endpoints only.",
|
|
218
|
+
"type": "boolean"
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
},
|
|
222
|
+
"modelSpec": {
|
|
223
|
+
"description": "A named model configuration. The object form is what carries the knobs a shorthand cannot.",
|
|
224
|
+
"type": "object",
|
|
225
|
+
"required": ["model"],
|
|
226
|
+
"additionalProperties": false,
|
|
227
|
+
"properties": {
|
|
228
|
+
"provider": {
|
|
229
|
+
"description": "A name from `providers:`, or a built-in kind.",
|
|
230
|
+
"type": "string",
|
|
231
|
+
"minLength": 1
|
|
232
|
+
},
|
|
233
|
+
"api": {
|
|
234
|
+
"description": "OpenAI protocol only — the other kinds speak one api, so naming this on a Gemini, Claude or OpenRouter model is an error rather than a field to ignore.",
|
|
235
|
+
"type": "string",
|
|
236
|
+
"enum": ["chat", "responses"]
|
|
237
|
+
},
|
|
238
|
+
"model": {
|
|
239
|
+
"description": "The id the api is sent, without a provider prefix.",
|
|
240
|
+
"type": "string",
|
|
241
|
+
"minLength": 1
|
|
242
|
+
},
|
|
243
|
+
"apiKey": { "$ref": "#/$defs/apiKey" },
|
|
244
|
+
"apiKeyEnv": { "$ref": "#/$defs/apiKeyEnv" },
|
|
245
|
+
"baseURL": { "$ref": "#/$defs/baseURL" },
|
|
246
|
+
"baseURLEnv": { "$ref": "#/$defs/baseURLEnv" },
|
|
247
|
+
"reasoningEffort": {
|
|
248
|
+
"description": "`minimal`, `low`, `medium`, `high` — a plain string on purpose: the vendor's accepted set changes faster than this file would, and the request that carries a bad value is the authority on rejecting it.",
|
|
249
|
+
"type": "string",
|
|
250
|
+
"minLength": 1
|
|
251
|
+
},
|
|
252
|
+
"reasoningSummary": {
|
|
253
|
+
"description": "How much of the reasoning is summarised back.",
|
|
254
|
+
"type": "string",
|
|
255
|
+
"enum": ["auto", "concise", "detailed"]
|
|
256
|
+
},
|
|
257
|
+
"store": {
|
|
258
|
+
"description": "OpenAI responses api — whether the provider keeps the conversation.",
|
|
259
|
+
"type": "boolean"
|
|
260
|
+
},
|
|
261
|
+
"maxTokens": {
|
|
262
|
+
"description": "anthropic only — the output cap its api requires.",
|
|
263
|
+
"type": "integer",
|
|
264
|
+
"exclusiveMinimum": 0
|
|
265
|
+
},
|
|
266
|
+
"thinkingBudgetTokens": {
|
|
267
|
+
"description": "anthropic only — the extended thinking budget.",
|
|
268
|
+
"type": "integer",
|
|
269
|
+
"exclusiveMinimum": 0
|
|
270
|
+
},
|
|
271
|
+
"thinkingBudget": {
|
|
272
|
+
"description": "gemini only — 2.5 takes a token budget.",
|
|
273
|
+
"type": "integer"
|
|
274
|
+
},
|
|
275
|
+
"thinkingLevel": {
|
|
276
|
+
"description": "gemini only — 3 takes a level instead of a budget.",
|
|
277
|
+
"type": "string",
|
|
278
|
+
"enum": ["minimal", "low", "medium", "high"]
|
|
279
|
+
},
|
|
280
|
+
"includeThoughts": {
|
|
281
|
+
"description": "gemini only — whether thought summaries come back.",
|
|
282
|
+
"type": "boolean"
|
|
283
|
+
},
|
|
284
|
+
"routing": {
|
|
285
|
+
"description": "openrouter only — who serves the request.",
|
|
286
|
+
"$ref": "#/$defs/routing"
|
|
287
|
+
},
|
|
288
|
+
"fallbacks": {
|
|
289
|
+
"description": "openrouter only — which models to try when no permitted provider can serve this one.",
|
|
290
|
+
"type": "array",
|
|
291
|
+
"minItems": 1,
|
|
292
|
+
"items": { "type": "string", "minLength": 1 }
|
|
293
|
+
},
|
|
294
|
+
"serviceTier": {
|
|
295
|
+
"description": "What the request is worth: which queue the provider puts it in.",
|
|
296
|
+
"type": "string",
|
|
297
|
+
"enum": ["auto", "default", "fast", "flex", "priority", "scale"]
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
},
|
|
301
|
+
"embeddingSpec": {
|
|
302
|
+
"description": "A vectoriser. Deliberately much smaller than a model: an embedding call has no conversation, no tools and no reasoning, so a connection, an id and a width is all there is to say.",
|
|
303
|
+
"type": "object",
|
|
304
|
+
"required": ["model"],
|
|
305
|
+
"additionalProperties": false,
|
|
306
|
+
"properties": {
|
|
307
|
+
"provider": {
|
|
308
|
+
"description": "A name from `providers:`, or a built-in kind.",
|
|
309
|
+
"type": "string",
|
|
310
|
+
"minLength": 1
|
|
311
|
+
},
|
|
312
|
+
"model": {
|
|
313
|
+
"description": "The id the api is sent, without a provider prefix.",
|
|
314
|
+
"type": "string",
|
|
315
|
+
"minLength": 1
|
|
316
|
+
},
|
|
317
|
+
"apiKey": { "$ref": "#/$defs/apiKey" },
|
|
318
|
+
"apiKeyEnv": { "$ref": "#/$defs/apiKeyEnv" },
|
|
319
|
+
"baseURL": { "$ref": "#/$defs/baseURL" },
|
|
320
|
+
"baseURLEnv": { "$ref": "#/$defs/baseURLEnv" },
|
|
321
|
+
"dimensions": {
|
|
322
|
+
"description": "Truncate to this width, where the model supports it. The width a store uses is learned from the first response, and changing it afterwards is refused rather than silently mixing two vector spaces.",
|
|
323
|
+
"type": "integer",
|
|
324
|
+
"exclusiveMinimum": 0
|
|
325
|
+
},
|
|
326
|
+
"title": {
|
|
327
|
+
"description": "gemini only — a document title the retrieval task type takes into account.",
|
|
328
|
+
"type": "string",
|
|
329
|
+
"minLength": 1
|
|
330
|
+
},
|
|
331
|
+
"maxBatch": {
|
|
332
|
+
"description": "Texts per request. Defaults to what the model is known to accept, so setting it is for a gateway whose caps are not the vendor's.",
|
|
333
|
+
"type": "integer",
|
|
334
|
+
"exclusiveMinimum": 0
|
|
335
|
+
},
|
|
336
|
+
"maxBatchTokens": {
|
|
337
|
+
"description": "Tokens per request, for the same reason as `maxBatch`.",
|
|
338
|
+
"type": "integer",
|
|
339
|
+
"exclusiveMinimum": 0
|
|
340
|
+
},
|
|
341
|
+
"routing": {
|
|
342
|
+
"description": "openrouter only — who serves the request.",
|
|
343
|
+
"$ref": "#/$defs/routing"
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
},
|
|
347
|
+
"skillsBinding": {
|
|
348
|
+
"description": "Which of the catalog this agent sees, and how it is offered — as an index of names and descriptions, as a search tool, or not at all. An agent with no `skills:` key is offered the whole catalog as an index.",
|
|
349
|
+
"type": "object",
|
|
350
|
+
"additionalProperties": false,
|
|
351
|
+
"properties": {
|
|
352
|
+
"provider": {
|
|
353
|
+
"description": "Skill provider id; defaults to the project's sole provider.",
|
|
354
|
+
"type": "string",
|
|
355
|
+
"minLength": 1
|
|
356
|
+
},
|
|
357
|
+
"discovery": {
|
|
358
|
+
"description": "`index` lists names and descriptions in the prompt, `search` gives a tool to look them up, `none` offers nothing — which needs a `preload:`, or the agent can reach no skill at all.",
|
|
359
|
+
"type": "string",
|
|
360
|
+
"enum": ["index", "search", "none"],
|
|
361
|
+
"default": "index"
|
|
362
|
+
},
|
|
363
|
+
"allow": {
|
|
364
|
+
"description": "Restricts the catalog this agent sees. Absent means all of it; `[]` means none.",
|
|
365
|
+
"type": "array",
|
|
366
|
+
"items": { "$ref": "#/$defs/name" }
|
|
367
|
+
},
|
|
368
|
+
"preload": {
|
|
369
|
+
"description": "Activated before the first call of every turn this agent owns, so they sit in the cached prefix rather than arriving mid-run.",
|
|
370
|
+
"type": "array",
|
|
371
|
+
"items": { "$ref": "#/$defs/name" }
|
|
372
|
+
},
|
|
373
|
+
"maxIndexEntries": {
|
|
374
|
+
"description": "Cap on how many skills the index lists.",
|
|
375
|
+
"type": "integer",
|
|
376
|
+
"exclusiveMinimum": 0
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
},
|
|
380
|
+
"forkBinding": {
|
|
381
|
+
"description": "Parallel sub-agents. The `fork` tool is gated on this binding existing, not on what it holds — so `true` and `{}` say the same thing, and an agent that never mentions `fork:` is never offered the tool.",
|
|
382
|
+
"type": "object",
|
|
383
|
+
"additionalProperties": false,
|
|
384
|
+
"properties": {
|
|
385
|
+
"agents": {
|
|
386
|
+
"description": "Agents a branch may run. Absent means any registered agent; `[]` would read as none while meaning only itself, so it is refused.",
|
|
387
|
+
"type": "array",
|
|
388
|
+
"minItems": 1,
|
|
389
|
+
"items": { "$ref": "#/$defs/name" }
|
|
390
|
+
},
|
|
391
|
+
"maxBranches": {
|
|
392
|
+
"description": "How wide one call may fan out. `1` allows delegation but no fan-out; `0` would make every call the model could write fail, so it is refused.",
|
|
393
|
+
"type": "integer",
|
|
394
|
+
"minimum": 1
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
},
|
|
398
|
+
"memoryBinding": {
|
|
399
|
+
"description": "What this agent may do with the project's one memory graph, and which slice of it it can see. `sees` and `writes` are here rather than in a tool schema on purpose: an agent that could name its own audience could read another agent's slice just by asking for it.",
|
|
400
|
+
"type": "object",
|
|
401
|
+
"additionalProperties": false,
|
|
402
|
+
"properties": {
|
|
403
|
+
"access": {
|
|
404
|
+
"description": "Which tools the agent is offered: `read` is search and load, `read-write` adds commit, `full` adds forget.",
|
|
405
|
+
"type": "string",
|
|
406
|
+
"enum": ["read", "read-write", "full"],
|
|
407
|
+
"default": "read-write"
|
|
408
|
+
},
|
|
409
|
+
"sees": {
|
|
410
|
+
"description": "Audience labels this agent may read, on top of the public slice. `*` is public and always readable, so this can only widen.",
|
|
411
|
+
"type": "array",
|
|
412
|
+
"items": { "$ref": "#/$defs/name" }
|
|
413
|
+
},
|
|
414
|
+
"writes": {
|
|
415
|
+
"description": "Labels it may put on what it writes.",
|
|
416
|
+
"type": "array",
|
|
417
|
+
"items": { "$ref": "#/$defs/name" }
|
|
418
|
+
},
|
|
419
|
+
"autoRecall": {
|
|
420
|
+
"description": "Recall before a turn that follows new user input — not before every call, which costs tokens and defeats prompt caching for a marginal gain. `false` leaves the agent the tools and lets it decide when to look.",
|
|
421
|
+
"default": true,
|
|
422
|
+
"oneOf": [
|
|
423
|
+
{ "type": "boolean" },
|
|
424
|
+
{
|
|
425
|
+
"type": "object",
|
|
426
|
+
"additionalProperties": false,
|
|
427
|
+
"properties": {
|
|
428
|
+
"limit": {
|
|
429
|
+
"description": "How many seeds a recall starts from.",
|
|
430
|
+
"type": "integer",
|
|
431
|
+
"exclusiveMinimum": 0,
|
|
432
|
+
"default": 5
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
]
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
},
|
|
440
|
+
"memoryConfig": {
|
|
441
|
+
"description": "Where the project's memory lives, and what vectorises it.",
|
|
442
|
+
"type": "object",
|
|
443
|
+
"additionalProperties": false,
|
|
444
|
+
"properties": {
|
|
445
|
+
"dir": {
|
|
446
|
+
"description": "Relative to the project root. Committed with the project — everything but the lock.",
|
|
447
|
+
"type": "string",
|
|
448
|
+
"minLength": 1,
|
|
449
|
+
"default": "memory"
|
|
450
|
+
},
|
|
451
|
+
"embedding": {
|
|
452
|
+
"description": "A name from `embeddings:`. Set it: without one, recall ranks by term overlap, which finds a memory phrased the way the question happened to be phrased and misses the rest.",
|
|
453
|
+
"$ref": "#/$defs/modelRef"
|
|
454
|
+
},
|
|
455
|
+
"kinds": {
|
|
456
|
+
"description": "Replaces the node vocabulary — `task`, `plan`, `fact`, `snippet`, `file`, `operation`, `preference`. A wider vocabulary is a vaguer one, and a kind nothing else understands is one no other agent can search for. `preference` is always available whatever this says.",
|
|
457
|
+
"type": "array",
|
|
458
|
+
"minItems": 1,
|
|
459
|
+
"items": { "$ref": "#/$defs/name" }
|
|
460
|
+
},
|
|
461
|
+
"relations": {
|
|
462
|
+
"description": "Replaces the edge vocabulary — `PRODUCED`, `CALLS`, `SUPERSEDES`, `INFORMED`.",
|
|
463
|
+
"type": "array",
|
|
464
|
+
"minItems": 1,
|
|
465
|
+
"items": { "$ref": "#/$defs/name" }
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
},
|
|
469
|
+
"build": {
|
|
470
|
+
"description": "A Dockerfile to build instead of an image to pull, for the case `image:` cannot serve: a project that needs two runtimes, or a pinned toolchain, and would otherwise have its agents reinstall it on every run.",
|
|
471
|
+
"type": "object",
|
|
472
|
+
"required": ["dockerfile"],
|
|
473
|
+
"additionalProperties": false,
|
|
474
|
+
"properties": {
|
|
475
|
+
"dockerfile": {
|
|
476
|
+
"description": "Path to the Dockerfile, relative to the project root.",
|
|
477
|
+
"type": "string",
|
|
478
|
+
"minLength": 1
|
|
479
|
+
},
|
|
480
|
+
"context": {
|
|
481
|
+
"description": "What the build may COPY from. The Dockerfile's own directory by default.",
|
|
482
|
+
"type": "string",
|
|
483
|
+
"minLength": 1
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
},
|
|
487
|
+
"sandbox": {
|
|
488
|
+
"description": "The container command-line tools run in. Everything here is a resource decision — which image, how much of the machine, whether the network is reachable — because those are the decisions that differ between a laptop and CI and cannot be baked into an image.",
|
|
489
|
+
"type": "object",
|
|
490
|
+
"additionalProperties": false,
|
|
491
|
+
"not": {
|
|
492
|
+
"description": "`image:` and `build:` cannot both be set — a Dockerfile names its own base in its FROM line, so one of the two would be silently ignored.",
|
|
493
|
+
"required": ["image", "build"]
|
|
494
|
+
},
|
|
495
|
+
"properties": {
|
|
496
|
+
"image": {
|
|
497
|
+
"description": "The image to pull, e.g. `docker.io/library/python:3.13-slim`.",
|
|
498
|
+
"type": "string",
|
|
499
|
+
"minLength": 1
|
|
500
|
+
},
|
|
501
|
+
"build": {
|
|
502
|
+
"description": "A Dockerfile to build, instead of an image to pull.",
|
|
503
|
+
"$ref": "#/$defs/build"
|
|
504
|
+
},
|
|
505
|
+
"cpus": {
|
|
506
|
+
"description": "Fractional cores the container may use.",
|
|
507
|
+
"type": "number",
|
|
508
|
+
"exclusiveMinimum": 0
|
|
509
|
+
},
|
|
510
|
+
"memory": {
|
|
511
|
+
"description": "MiB the container may use.",
|
|
512
|
+
"type": "integer",
|
|
513
|
+
"exclusiveMinimum": 0
|
|
514
|
+
},
|
|
515
|
+
"network": {
|
|
516
|
+
"description": "`none` is the honest answer for a container that only has to read the workspace.",
|
|
517
|
+
"type": "string",
|
|
518
|
+
"enum": ["bridge", "none", "host"]
|
|
519
|
+
},
|
|
520
|
+
"workdir": {
|
|
521
|
+
"description": "Where the workspace is mounted, and the default working directory.",
|
|
522
|
+
"type": "string",
|
|
523
|
+
"minLength": 1
|
|
524
|
+
},
|
|
525
|
+
"timeout": {
|
|
526
|
+
"description": "Seconds one command may take before it is killed.",
|
|
527
|
+
"type": "integer",
|
|
528
|
+
"exclusiveMinimum": 0
|
|
529
|
+
},
|
|
530
|
+
"user": {
|
|
531
|
+
"description": "uid, name or `uid:gid`. Unset means the image's own user.",
|
|
532
|
+
"type": "string",
|
|
533
|
+
"minLength": 1
|
|
534
|
+
},
|
|
535
|
+
"persist": {
|
|
536
|
+
"description": "Keep the container between sessions rather than throwing it away, so what an agent installs for itself is still there next time. Otherwise only the workspace and the home directory survive.",
|
|
537
|
+
"type": "boolean"
|
|
538
|
+
},
|
|
539
|
+
"env": {
|
|
540
|
+
"description": "Host variables to forward, by name. Only names: a value never appears in this file, so a repository never carries one. Model credentials go through `keys:` instead, which is one switch rather than a second silent door.",
|
|
541
|
+
"type": "array",
|
|
542
|
+
"items": { "type": "string", "minLength": 1 }
|
|
543
|
+
},
|
|
544
|
+
"keys": {
|
|
545
|
+
"description": "Whether the model credentials reach the sandbox. On by default, because the scaffolded image installs `zen` itself. Turning it off is the honest answer for a project whose agents write code they then execute: the container runs whatever the model wrote.",
|
|
546
|
+
"type": "boolean",
|
|
547
|
+
"default": true
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
},
|
|
551
|
+
"agent": {
|
|
552
|
+
"description": "An agent is an instruction, a model, a set of tools and what it can know on demand — plus who it may hand off to, and whether it may fork. There is no hidden orchestration layer.",
|
|
553
|
+
"type": "object",
|
|
554
|
+
"required": ["name"],
|
|
555
|
+
"additionalProperties": false,
|
|
556
|
+
"properties": {
|
|
557
|
+
"name": {
|
|
558
|
+
"description": "Also the name of its prompt file, `agents/prompts/<name>.md`, which is picked up by convention.",
|
|
559
|
+
"$ref": "#/$defs/name"
|
|
560
|
+
},
|
|
561
|
+
"description": {
|
|
562
|
+
"description": "What a sibling's `transfer_to_<name>` tool tells the model. This is what routes work, so write it as the condition for handing over rather than as a job title.",
|
|
563
|
+
"type": "string"
|
|
564
|
+
},
|
|
565
|
+
"system": {
|
|
566
|
+
"description": "Path to a markdown file, relative to the project root. Only needed when the prompt is not at `agents/prompts/<name>.md`.",
|
|
567
|
+
"type": "string",
|
|
568
|
+
"minLength": 1
|
|
569
|
+
},
|
|
570
|
+
"model": {
|
|
571
|
+
"description": "Pins this agent's model. Without one it uses the project's.",
|
|
572
|
+
"$ref": "#/$defs/modelRef"
|
|
573
|
+
},
|
|
574
|
+
"tools": {
|
|
575
|
+
"description": "Tool names and selectors: `workspace:*` is every file tool, `sandbox:*` the shell, `exa:*` web search and page reading. Subtract from a group with a leading `-`.",
|
|
576
|
+
"type": "array",
|
|
577
|
+
"items": { "type": "string", "minLength": 1 },
|
|
578
|
+
"examples": [
|
|
579
|
+
["workspace:*", "sandbox:*"],
|
|
580
|
+
["workspace:*", "-delete_file"]
|
|
581
|
+
]
|
|
582
|
+
},
|
|
583
|
+
"handoffs": {
|
|
584
|
+
"description": "Agents this one may transfer control to, by name. Plain names: a hand-off carries no configuration, so there is nothing an object form could hold.",
|
|
585
|
+
"type": "array",
|
|
586
|
+
"items": { "$ref": "#/$defs/name" }
|
|
587
|
+
},
|
|
588
|
+
"skills": {
|
|
589
|
+
"description": "Which skills this agent sees, and how. Absent means the whole catalog as an index; `allow: []` binds none.",
|
|
590
|
+
"$ref": "#/$defs/skillsBinding"
|
|
591
|
+
},
|
|
592
|
+
"fork": {
|
|
593
|
+
"description": "Parallel sub-agents. `true` is the unrestricted form; the tool is offered only when this key is present.",
|
|
594
|
+
"oneOf": [{ "type": "boolean" }, { "$ref": "#/$defs/forkBinding" }]
|
|
595
|
+
},
|
|
596
|
+
"memory": {
|
|
597
|
+
"description": "The shared memory graph. `true` is the whole feature working the obvious way — read and write, with auto-recall on. Drop the key and this agent never sees the store.",
|
|
598
|
+
"oneOf": [{ "type": "boolean" }, { "$ref": "#/$defs/memoryBinding" }]
|
|
599
|
+
},
|
|
600
|
+
"sandbox": {
|
|
601
|
+
"description": "Overrides on the project's sandbox. An agent that overrides nothing shares the container with everyone else; one that names its own image gets its own.",
|
|
602
|
+
"$ref": "#/$defs/sandbox"
|
|
603
|
+
},
|
|
604
|
+
"default": {
|
|
605
|
+
"description": "The entry point, when no top-level `default:` names one.",
|
|
606
|
+
"type": "boolean"
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
}
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"chat.useNestedAgentsMdFiles": false,
|
|
3
|
+
"yaml.schemas": {
|
|
4
|
+
"./.vscode/agents.schema.json": [
|
|
5
|
+
"agents.yaml",
|
|
6
|
+
"agents.yml",
|
|
7
|
+
"agents/agents.yaml",
|
|
8
|
+
"agents/agents.yml"
|
|
9
|
+
]
|
|
10
|
+
},
|
|
3
11
|
"chat.tools.terminal.enableAutoApprove": true,
|
|
4
12
|
"chat.tools.edits.autoApprove": true,
|
|
5
13
|
"chat.tools.terminal.autoApprove": {
|