@omnidev-ai/core 0.3.0 → 0.5.0
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/dist/index.d.ts +825 -0
- package/dist/index.js +2099 -0
- package/dist/shared/chunk-1dqs11h6.js +20 -0
- package/dist/test-utils/index.d.ts +138 -0
- package/dist/test-utils/index.js +230 -0
- package/package.json +17 -5
- package/src/test-utils/helpers.ts +14 -9
- package/src/capability/commands.test.ts +0 -410
- package/src/capability/docs.test.ts +0 -192
- package/src/capability/loader.test.ts +0 -668
- package/src/capability/registry.test.ts +0 -455
- package/src/capability/rules.test.ts +0 -135
- package/src/capability/skills.test.ts +0 -312
- package/src/capability/sources.test.ts +0 -439
- package/src/capability/subagents.test.ts +0 -474
- package/src/capability/wrapping-integration.test.ts +0 -412
- package/src/config/env.test.ts +0 -270
- package/src/config/loader.test.ts +0 -198
- package/src/config/parser.test.ts +0 -256
- package/src/config/profiles.test.ts +0 -222
- package/src/config/provider.test.ts +0 -66
- package/src/index.test.ts +0 -26
- package/src/mcp-json/manager.test.ts +0 -310
- package/src/state/active-profile.test.ts +0 -117
- package/src/state/manifest.test.ts +0 -411
- package/src/state/providers.test.ts +0 -125
- package/src/templates/agents.test.ts +0 -23
- package/src/templates/claude.test.ts +0 -48
- package/src/test-utils/helpers.test.ts +0 -214
- package/src/test-utils/mocks.test.ts +0 -83
- package/src/types/index.test.ts +0 -28
|
@@ -1,474 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, test } from "bun:test";
|
|
2
|
-
import { mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
3
|
-
import { join } from "node:path";
|
|
4
|
-
import { setupTestDir } from "@omnidev-ai/core/test-utils";
|
|
5
|
-
import { loadSubagents } from "./subagents";
|
|
6
|
-
|
|
7
|
-
describe("loadSubagents", () => {
|
|
8
|
-
const testDir = setupTestDir("capability-subagents-test-");
|
|
9
|
-
let capabilityPath: string;
|
|
10
|
-
|
|
11
|
-
beforeEach(() => {
|
|
12
|
-
capabilityPath = join(testDir.path, "test-capability");
|
|
13
|
-
mkdirSync(capabilityPath, { recursive: true });
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
test("returns empty array when subagents directory does not exist", async () => {
|
|
17
|
-
const subagents = await loadSubagents(capabilityPath, "test-cap");
|
|
18
|
-
expect(subagents).toEqual([]);
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
test("returns empty array when subagents directory is empty", async () => {
|
|
22
|
-
mkdirSync(join(capabilityPath, "subagents"), { recursive: true });
|
|
23
|
-
const subagents = await loadSubagents(capabilityPath, "test-cap");
|
|
24
|
-
expect(subagents).toEqual([]);
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
test("loads single subagent with valid frontmatter and system prompt", async () => {
|
|
28
|
-
const subagentDir = join(capabilityPath, "subagents", "test-subagent");
|
|
29
|
-
mkdirSync(subagentDir, { recursive: true });
|
|
30
|
-
|
|
31
|
-
const subagentContent = `---
|
|
32
|
-
name: test-subagent
|
|
33
|
-
description: A test subagent
|
|
34
|
-
---
|
|
35
|
-
|
|
36
|
-
You are a test subagent.
|
|
37
|
-
|
|
38
|
-
## Instructions
|
|
39
|
-
|
|
40
|
-
Do testing things.`;
|
|
41
|
-
|
|
42
|
-
writeFileSync(join(subagentDir, "SUBAGENT.md"), subagentContent);
|
|
43
|
-
|
|
44
|
-
const subagents = await loadSubagents(capabilityPath, "test-cap");
|
|
45
|
-
|
|
46
|
-
expect(subagents).toHaveLength(1);
|
|
47
|
-
expect(subagents[0]).toEqual({
|
|
48
|
-
name: "test-subagent",
|
|
49
|
-
description: "A test subagent",
|
|
50
|
-
systemPrompt: "You are a test subagent.\n\n## Instructions\n\nDo testing things.",
|
|
51
|
-
capabilityId: "test-cap",
|
|
52
|
-
});
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
test("loads subagent with tools field", async () => {
|
|
56
|
-
const subagentDir = join(capabilityPath, "subagents", "tools-subagent");
|
|
57
|
-
mkdirSync(subagentDir, { recursive: true });
|
|
58
|
-
|
|
59
|
-
const subagentContent = `---
|
|
60
|
-
name: tools-subagent
|
|
61
|
-
description: Subagent with tools
|
|
62
|
-
tools: Read, Glob, Grep
|
|
63
|
-
---
|
|
64
|
-
|
|
65
|
-
System prompt here.`;
|
|
66
|
-
|
|
67
|
-
writeFileSync(join(subagentDir, "SUBAGENT.md"), subagentContent);
|
|
68
|
-
|
|
69
|
-
const subagents = await loadSubagents(capabilityPath, "test-cap");
|
|
70
|
-
|
|
71
|
-
expect(subagents).toHaveLength(1);
|
|
72
|
-
expect(subagents[0]?.tools).toEqual(["Read", "Glob", "Grep"]);
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
test("loads subagent with disallowedTools field", async () => {
|
|
76
|
-
const subagentDir = join(capabilityPath, "subagents", "disallowed-subagent");
|
|
77
|
-
mkdirSync(subagentDir, { recursive: true });
|
|
78
|
-
|
|
79
|
-
const subagentContent = `---
|
|
80
|
-
name: disallowed-subagent
|
|
81
|
-
description: Subagent with disallowed tools
|
|
82
|
-
disallowedTools: Write, Edit
|
|
83
|
-
---
|
|
84
|
-
|
|
85
|
-
System prompt here.`;
|
|
86
|
-
|
|
87
|
-
writeFileSync(join(subagentDir, "SUBAGENT.md"), subagentContent);
|
|
88
|
-
|
|
89
|
-
const subagents = await loadSubagents(capabilityPath, "test-cap");
|
|
90
|
-
|
|
91
|
-
expect(subagents).toHaveLength(1);
|
|
92
|
-
expect(subagents[0]?.disallowedTools).toEqual(["Write", "Edit"]);
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
test("loads subagent with model field", async () => {
|
|
96
|
-
const subagentDir = join(capabilityPath, "subagents", "model-subagent");
|
|
97
|
-
mkdirSync(subagentDir, { recursive: true });
|
|
98
|
-
|
|
99
|
-
const subagentContent = `---
|
|
100
|
-
name: model-subagent
|
|
101
|
-
description: Subagent with model
|
|
102
|
-
model: haiku
|
|
103
|
-
---
|
|
104
|
-
|
|
105
|
-
System prompt here.`;
|
|
106
|
-
|
|
107
|
-
writeFileSync(join(subagentDir, "SUBAGENT.md"), subagentContent);
|
|
108
|
-
|
|
109
|
-
const subagents = await loadSubagents(capabilityPath, "test-cap");
|
|
110
|
-
|
|
111
|
-
expect(subagents).toHaveLength(1);
|
|
112
|
-
expect(subagents[0]?.model).toBe("haiku");
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
test("loads subagent with permissionMode field", async () => {
|
|
116
|
-
const subagentDir = join(capabilityPath, "subagents", "permission-subagent");
|
|
117
|
-
mkdirSync(subagentDir, { recursive: true });
|
|
118
|
-
|
|
119
|
-
const subagentContent = `---
|
|
120
|
-
name: permission-subagent
|
|
121
|
-
description: Subagent with permission mode
|
|
122
|
-
permissionMode: dontAsk
|
|
123
|
-
---
|
|
124
|
-
|
|
125
|
-
System prompt here.`;
|
|
126
|
-
|
|
127
|
-
writeFileSync(join(subagentDir, "SUBAGENT.md"), subagentContent);
|
|
128
|
-
|
|
129
|
-
const subagents = await loadSubagents(capabilityPath, "test-cap");
|
|
130
|
-
|
|
131
|
-
expect(subagents).toHaveLength(1);
|
|
132
|
-
expect(subagents[0]?.permissionMode).toBe("dontAsk");
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
test("loads subagent with skills field", async () => {
|
|
136
|
-
const subagentDir = join(capabilityPath, "subagents", "skills-subagent");
|
|
137
|
-
mkdirSync(subagentDir, { recursive: true });
|
|
138
|
-
|
|
139
|
-
const subagentContent = `---
|
|
140
|
-
name: skills-subagent
|
|
141
|
-
description: Subagent with skills
|
|
142
|
-
skills: prd, ralph
|
|
143
|
-
---
|
|
144
|
-
|
|
145
|
-
System prompt here.`;
|
|
146
|
-
|
|
147
|
-
writeFileSync(join(subagentDir, "SUBAGENT.md"), subagentContent);
|
|
148
|
-
|
|
149
|
-
const subagents = await loadSubagents(capabilityPath, "test-cap");
|
|
150
|
-
|
|
151
|
-
expect(subagents).toHaveLength(1);
|
|
152
|
-
expect(subagents[0]?.skills).toEqual(["prd", "ralph"]);
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
test("loads subagent with all optional fields", async () => {
|
|
156
|
-
const subagentDir = join(capabilityPath, "subagents", "full-subagent");
|
|
157
|
-
mkdirSync(subagentDir, { recursive: true });
|
|
158
|
-
|
|
159
|
-
const subagentContent = `---
|
|
160
|
-
name: full-subagent
|
|
161
|
-
description: Subagent with all fields
|
|
162
|
-
tools: Read, Glob, Grep, Bash
|
|
163
|
-
disallowedTools: Write, Edit
|
|
164
|
-
model: sonnet
|
|
165
|
-
permissionMode: acceptEdits
|
|
166
|
-
skills: prd, ralph, capability-builder
|
|
167
|
-
---
|
|
168
|
-
|
|
169
|
-
You are a fully configured subagent.`;
|
|
170
|
-
|
|
171
|
-
writeFileSync(join(subagentDir, "SUBAGENT.md"), subagentContent);
|
|
172
|
-
|
|
173
|
-
const subagents = await loadSubagents(capabilityPath, "test-cap");
|
|
174
|
-
|
|
175
|
-
expect(subagents).toHaveLength(1);
|
|
176
|
-
expect(subagents[0]?.name).toBe("full-subagent");
|
|
177
|
-
expect(subagents[0]?.description).toBe("Subagent with all fields");
|
|
178
|
-
expect(subagents[0]?.tools).toEqual(["Read", "Glob", "Grep", "Bash"]);
|
|
179
|
-
expect(subagents[0]?.disallowedTools).toEqual(["Write", "Edit"]);
|
|
180
|
-
expect(subagents[0]?.model).toBe("sonnet");
|
|
181
|
-
expect(subagents[0]?.permissionMode).toBe("acceptEdits");
|
|
182
|
-
expect(subagents[0]?.skills).toEqual(["prd", "ralph", "capability-builder"]);
|
|
183
|
-
expect(subagents[0]?.systemPrompt).toBe("You are a fully configured subagent.");
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
test("loads multiple subagents from different directories", async () => {
|
|
187
|
-
const subagent1Dir = join(capabilityPath, "subagents", "subagent-1");
|
|
188
|
-
const subagent2Dir = join(capabilityPath, "subagents", "subagent-2");
|
|
189
|
-
mkdirSync(subagent1Dir, { recursive: true });
|
|
190
|
-
mkdirSync(subagent2Dir, { recursive: true });
|
|
191
|
-
|
|
192
|
-
writeFileSync(
|
|
193
|
-
join(subagent1Dir, "SUBAGENT.md"),
|
|
194
|
-
`---
|
|
195
|
-
name: subagent-1
|
|
196
|
-
description: First subagent
|
|
197
|
-
---
|
|
198
|
-
|
|
199
|
-
First subagent prompt.`,
|
|
200
|
-
);
|
|
201
|
-
|
|
202
|
-
writeFileSync(
|
|
203
|
-
join(subagent2Dir, "SUBAGENT.md"),
|
|
204
|
-
`---
|
|
205
|
-
name: subagent-2
|
|
206
|
-
description: Second subagent
|
|
207
|
-
---
|
|
208
|
-
|
|
209
|
-
Second subagent prompt.`,
|
|
210
|
-
);
|
|
211
|
-
|
|
212
|
-
const subagents = await loadSubagents(capabilityPath, "test-cap");
|
|
213
|
-
|
|
214
|
-
expect(subagents).toHaveLength(2);
|
|
215
|
-
expect(subagents[0]?.name).toBe("subagent-1");
|
|
216
|
-
expect(subagents[1]?.name).toBe("subagent-2");
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
test("skips subagent directories without SUBAGENT.md file", async () => {
|
|
220
|
-
const validDir = join(capabilityPath, "subagents", "valid-subagent");
|
|
221
|
-
const invalidDir = join(capabilityPath, "subagents", "no-file");
|
|
222
|
-
mkdirSync(validDir, { recursive: true });
|
|
223
|
-
mkdirSync(invalidDir, { recursive: true });
|
|
224
|
-
|
|
225
|
-
writeFileSync(
|
|
226
|
-
join(validDir, "SUBAGENT.md"),
|
|
227
|
-
`---
|
|
228
|
-
name: valid-subagent
|
|
229
|
-
description: Valid subagent
|
|
230
|
-
---
|
|
231
|
-
|
|
232
|
-
Valid prompt.`,
|
|
233
|
-
);
|
|
234
|
-
|
|
235
|
-
// No SUBAGENT.md in invalidDir
|
|
236
|
-
|
|
237
|
-
const subagents = await loadSubagents(capabilityPath, "test-cap");
|
|
238
|
-
|
|
239
|
-
expect(subagents).toHaveLength(1);
|
|
240
|
-
expect(subagents[0]?.name).toBe("valid-subagent");
|
|
241
|
-
});
|
|
242
|
-
|
|
243
|
-
test("handles YAML frontmatter with quoted values", async () => {
|
|
244
|
-
const subagentDir = join(capabilityPath, "subagents", "quoted-subagent");
|
|
245
|
-
mkdirSync(subagentDir, { recursive: true });
|
|
246
|
-
|
|
247
|
-
const subagentContent = `---
|
|
248
|
-
name: "quoted-subagent"
|
|
249
|
-
description: "A subagent with quoted values"
|
|
250
|
-
---
|
|
251
|
-
|
|
252
|
-
System prompt here.`;
|
|
253
|
-
|
|
254
|
-
writeFileSync(join(subagentDir, "SUBAGENT.md"), subagentContent);
|
|
255
|
-
|
|
256
|
-
const subagents = await loadSubagents(capabilityPath, "test-cap");
|
|
257
|
-
|
|
258
|
-
expect(subagents).toHaveLength(1);
|
|
259
|
-
expect(subagents[0]?.name).toBe("quoted-subagent");
|
|
260
|
-
expect(subagents[0]?.description).toBe("A subagent with quoted values");
|
|
261
|
-
});
|
|
262
|
-
|
|
263
|
-
test("trims whitespace from system prompt", async () => {
|
|
264
|
-
const subagentDir = join(capabilityPath, "subagents", "whitespace-subagent");
|
|
265
|
-
mkdirSync(subagentDir, { recursive: true });
|
|
266
|
-
|
|
267
|
-
const subagentContent = `---
|
|
268
|
-
name: whitespace-subagent
|
|
269
|
-
description: Test whitespace trimming
|
|
270
|
-
---
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
System prompt with leading/trailing whitespace.
|
|
274
|
-
|
|
275
|
-
`;
|
|
276
|
-
|
|
277
|
-
writeFileSync(join(subagentDir, "SUBAGENT.md"), subagentContent);
|
|
278
|
-
|
|
279
|
-
const subagents = await loadSubagents(capabilityPath, "test-cap");
|
|
280
|
-
|
|
281
|
-
expect(subagents).toHaveLength(1);
|
|
282
|
-
expect(subagents[0]?.systemPrompt).toBe("System prompt with leading/trailing whitespace.");
|
|
283
|
-
});
|
|
284
|
-
|
|
285
|
-
test("throws error when SUBAGENT.md has no frontmatter", async () => {
|
|
286
|
-
const subagentDir = join(capabilityPath, "subagents", "no-frontmatter");
|
|
287
|
-
mkdirSync(subagentDir, { recursive: true });
|
|
288
|
-
|
|
289
|
-
const subagentContent = `# Just Instructions
|
|
290
|
-
|
|
291
|
-
No frontmatter here.`;
|
|
292
|
-
|
|
293
|
-
writeFileSync(join(subagentDir, "SUBAGENT.md"), subagentContent);
|
|
294
|
-
|
|
295
|
-
await expect(loadSubagents(capabilityPath, "test-cap")).rejects.toThrow(
|
|
296
|
-
/Invalid SUBAGENT\.md format.*missing YAML frontmatter/,
|
|
297
|
-
);
|
|
298
|
-
});
|
|
299
|
-
|
|
300
|
-
test("throws error when SUBAGENT.md is missing name field", async () => {
|
|
301
|
-
const subagentDir = join(capabilityPath, "subagents", "missing-name");
|
|
302
|
-
mkdirSync(subagentDir, { recursive: true });
|
|
303
|
-
|
|
304
|
-
const subagentContent = `---
|
|
305
|
-
description: Missing name field
|
|
306
|
-
---
|
|
307
|
-
|
|
308
|
-
System prompt here.`;
|
|
309
|
-
|
|
310
|
-
writeFileSync(join(subagentDir, "SUBAGENT.md"), subagentContent);
|
|
311
|
-
|
|
312
|
-
await expect(loadSubagents(capabilityPath, "test-cap")).rejects.toThrow(
|
|
313
|
-
/name and description required/,
|
|
314
|
-
);
|
|
315
|
-
});
|
|
316
|
-
|
|
317
|
-
test("throws error when SUBAGENT.md is missing description field", async () => {
|
|
318
|
-
const subagentDir = join(capabilityPath, "subagents", "missing-description");
|
|
319
|
-
mkdirSync(subagentDir, { recursive: true });
|
|
320
|
-
|
|
321
|
-
const subagentContent = `---
|
|
322
|
-
name: missing-description
|
|
323
|
-
---
|
|
324
|
-
|
|
325
|
-
System prompt here.`;
|
|
326
|
-
|
|
327
|
-
writeFileSync(join(subagentDir, "SUBAGENT.md"), subagentContent);
|
|
328
|
-
|
|
329
|
-
await expect(loadSubagents(capabilityPath, "test-cap")).rejects.toThrow(
|
|
330
|
-
/name and description required/,
|
|
331
|
-
);
|
|
332
|
-
});
|
|
333
|
-
|
|
334
|
-
test("handles empty system prompt after frontmatter", async () => {
|
|
335
|
-
const subagentDir = join(capabilityPath, "subagents", "empty-prompt");
|
|
336
|
-
mkdirSync(subagentDir, { recursive: true });
|
|
337
|
-
|
|
338
|
-
const subagentContent = `---
|
|
339
|
-
name: empty-prompt
|
|
340
|
-
description: Subagent with no prompt
|
|
341
|
-
---
|
|
342
|
-
`;
|
|
343
|
-
|
|
344
|
-
writeFileSync(join(subagentDir, "SUBAGENT.md"), subagentContent);
|
|
345
|
-
|
|
346
|
-
const subagents = await loadSubagents(capabilityPath, "test-cap");
|
|
347
|
-
|
|
348
|
-
expect(subagents).toHaveLength(1);
|
|
349
|
-
expect(subagents[0]?.systemPrompt).toBe("");
|
|
350
|
-
});
|
|
351
|
-
|
|
352
|
-
test("preserves markdown formatting in system prompt", async () => {
|
|
353
|
-
const subagentDir = join(capabilityPath, "subagents", "markdown-subagent");
|
|
354
|
-
mkdirSync(subagentDir, { recursive: true });
|
|
355
|
-
|
|
356
|
-
const subagentContent = `---
|
|
357
|
-
name: markdown-subagent
|
|
358
|
-
description: Subagent with markdown
|
|
359
|
-
---
|
|
360
|
-
|
|
361
|
-
# Header
|
|
362
|
-
|
|
363
|
-
- List item 1
|
|
364
|
-
- List item 2
|
|
365
|
-
|
|
366
|
-
**Bold text** and *italic text*.
|
|
367
|
-
|
|
368
|
-
\`\`\`typescript
|
|
369
|
-
const code = "example";
|
|
370
|
-
\`\`\``;
|
|
371
|
-
|
|
372
|
-
writeFileSync(join(subagentDir, "SUBAGENT.md"), subagentContent);
|
|
373
|
-
|
|
374
|
-
const subagents = await loadSubagents(capabilityPath, "test-cap");
|
|
375
|
-
|
|
376
|
-
expect(subagents).toHaveLength(1);
|
|
377
|
-
expect(subagents[0]?.systemPrompt).toContain("# Header");
|
|
378
|
-
expect(subagents[0]?.systemPrompt).toContain("- List item 1");
|
|
379
|
-
expect(subagents[0]?.systemPrompt).toContain("**Bold text**");
|
|
380
|
-
expect(subagents[0]?.systemPrompt).toContain("```typescript");
|
|
381
|
-
});
|
|
382
|
-
|
|
383
|
-
test("ignores non-directory entries in subagents folder", async () => {
|
|
384
|
-
const subagentsDir = join(capabilityPath, "subagents");
|
|
385
|
-
const validDir = join(subagentsDir, "valid-subagent");
|
|
386
|
-
mkdirSync(validDir, { recursive: true });
|
|
387
|
-
|
|
388
|
-
writeFileSync(
|
|
389
|
-
join(validDir, "SUBAGENT.md"),
|
|
390
|
-
`---
|
|
391
|
-
name: valid-subagent
|
|
392
|
-
description: Valid subagent
|
|
393
|
-
---
|
|
394
|
-
|
|
395
|
-
Valid prompt.`,
|
|
396
|
-
);
|
|
397
|
-
|
|
398
|
-
// Create a file directly in subagents/ directory (should be ignored)
|
|
399
|
-
writeFileSync(join(subagentsDir, "README.md"), "This should be ignored");
|
|
400
|
-
|
|
401
|
-
const subagents = await loadSubagents(capabilityPath, "test-cap");
|
|
402
|
-
|
|
403
|
-
expect(subagents).toHaveLength(1);
|
|
404
|
-
expect(subagents[0]?.name).toBe("valid-subagent");
|
|
405
|
-
});
|
|
406
|
-
|
|
407
|
-
test("associates subagents with correct capability ID", async () => {
|
|
408
|
-
const subagentDir = join(capabilityPath, "subagents", "test-subagent");
|
|
409
|
-
mkdirSync(subagentDir, { recursive: true });
|
|
410
|
-
|
|
411
|
-
writeFileSync(
|
|
412
|
-
join(subagentDir, "SUBAGENT.md"),
|
|
413
|
-
`---
|
|
414
|
-
name: test-subagent
|
|
415
|
-
description: Test subagent
|
|
416
|
-
---
|
|
417
|
-
|
|
418
|
-
System prompt.`,
|
|
419
|
-
);
|
|
420
|
-
|
|
421
|
-
const subagents = await loadSubagents(capabilityPath, "my-capability");
|
|
422
|
-
|
|
423
|
-
expect(subagents).toHaveLength(1);
|
|
424
|
-
expect(subagents[0]?.capabilityId).toBe("my-capability");
|
|
425
|
-
});
|
|
426
|
-
|
|
427
|
-
test("model field accepts inherit value", async () => {
|
|
428
|
-
const subagentDir = join(capabilityPath, "subagents", "inherit-model");
|
|
429
|
-
mkdirSync(subagentDir, { recursive: true });
|
|
430
|
-
|
|
431
|
-
const subagentContent = `---
|
|
432
|
-
name: inherit-model
|
|
433
|
-
description: Subagent with inherit model
|
|
434
|
-
model: inherit
|
|
435
|
-
---
|
|
436
|
-
|
|
437
|
-
System prompt here.`;
|
|
438
|
-
|
|
439
|
-
writeFileSync(join(subagentDir, "SUBAGENT.md"), subagentContent);
|
|
440
|
-
|
|
441
|
-
const subagents = await loadSubagents(capabilityPath, "test-cap");
|
|
442
|
-
|
|
443
|
-
expect(subagents).toHaveLength(1);
|
|
444
|
-
expect(subagents[0]?.model).toBe("inherit");
|
|
445
|
-
});
|
|
446
|
-
|
|
447
|
-
test("permissionMode field accepts all valid values", async () => {
|
|
448
|
-
const modes = ["default", "acceptEdits", "dontAsk", "bypassPermissions", "plan"] as const;
|
|
449
|
-
|
|
450
|
-
for (const mode of modes) {
|
|
451
|
-
// Clean up from previous iteration
|
|
452
|
-
const subagentsDir = join(capabilityPath, "subagents");
|
|
453
|
-
rmSync(subagentsDir, { recursive: true, force: true });
|
|
454
|
-
|
|
455
|
-
const subagentDir = join(capabilityPath, "subagents", `${mode}-subagent`);
|
|
456
|
-
mkdirSync(subagentDir, { recursive: true });
|
|
457
|
-
|
|
458
|
-
const subagentContent = `---
|
|
459
|
-
name: ${mode}-subagent
|
|
460
|
-
description: Subagent with ${mode} permission mode
|
|
461
|
-
permissionMode: ${mode}
|
|
462
|
-
---
|
|
463
|
-
|
|
464
|
-
System prompt here.`;
|
|
465
|
-
|
|
466
|
-
writeFileSync(join(subagentDir, "SUBAGENT.md"), subagentContent);
|
|
467
|
-
|
|
468
|
-
const subagents = await loadSubagents(capabilityPath, "test-cap");
|
|
469
|
-
|
|
470
|
-
expect(subagents).toHaveLength(1);
|
|
471
|
-
expect(subagents[0]?.permissionMode).toBe(mode);
|
|
472
|
-
}
|
|
473
|
-
});
|
|
474
|
-
});
|