feat: add packaging and validation coverage

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Copilot CLI
2026-03-21 09:30:37 +01:00
co-authored by Copilot
parent 9e509593d6
commit c8d23f91d1
11 changed files with 556 additions and 76 deletions
+62 -2
View File
@@ -2,9 +2,11 @@ import { describe, expect, test } from 'bun:test';
import { createBuiltinPatterns, validatePatternDefinition } from '@shared/domain/pattern';
const BUILTIN_TIMESTAMP = '2026-03-22T00:00:00.000Z';
describe('pattern validation', () => {
test('builtin patterns are valid except explicitly unavailable modes', () => {
const patterns = createBuiltinPatterns('2026-03-22T00:00:00.000Z');
const patterns = createBuiltinPatterns(BUILTIN_TIMESTAMP);
const validPatterns = patterns.filter((pattern) => pattern.availability !== 'unavailable');
@@ -14,11 +16,69 @@ describe('pattern validation', () => {
});
test('magentic pattern is marked unavailable', () => {
const magentic = createBuiltinPatterns('2026-03-22T00:00:00.000Z').find(
const magentic = createBuiltinPatterns(BUILTIN_TIMESTAMP).find(
(pattern) => pattern.mode === 'magentic',
);
expect(magentic).toBeDefined();
expect(validatePatternDefinition(magentic!)[0]?.message).toContain('unsupported');
});
test('single-agent mode reports agent count, warning, and model issues together', () => {
const singlePattern = createBuiltinPatterns(BUILTIN_TIMESTAMP).find(
(pattern) => pattern.mode === 'single',
);
expect(singlePattern).toBeDefined();
const issues = validatePatternDefinition({
...singlePattern!,
agents: [
{
...singlePattern!.agents[0],
instructions: ' ',
},
{
...singlePattern!.agents[0],
id: 'agent-reviewer',
name: 'Reviewer',
model: '',
},
],
});
expect(issues.find((issue) => issue.field === 'agents')?.message).toBe(
'Single-agent chat requires exactly one agent.',
);
expect(issues.find((issue) => issue.field === 'agents.instructions')?.level).toBe('warning');
expect(issues.find((issue) => issue.field === 'agents.instructions')?.message).toBe(
'Agent "Primary Agent" should have instructions.',
);
expect(issues.find((issue) => issue.field === 'agents.model')?.message).toBe(
'Agent "Reviewer" requires a model identifier.',
);
});
test('multi-agent orchestration modes reject single-agent configurations', () => {
const patterns = createBuiltinPatterns(BUILTIN_TIMESTAMP);
const handoff = patterns.find((pattern) => pattern.mode === 'handoff');
const groupChat = patterns.find((pattern) => pattern.mode === 'group-chat');
expect(handoff).toBeDefined();
expect(groupChat).toBeDefined();
expect(
validatePatternDefinition({
...handoff!,
agents: handoff!.agents.slice(0, 1),
}).find((issue) => issue.field === 'agents')?.message,
).toBe('Handoff orchestration requires at least two agents.');
expect(
validatePatternDefinition({
...groupChat!,
agents: groupChat!.agents.slice(0, 1),
}).find((issue) => issue.field === 'agents')?.message,
).toBe('Group chat requires at least two agents.');
});
});
+34
View File
@@ -0,0 +1,34 @@
import { describe, expect, test } from 'bun:test';
import { createWorkspaceSeed } from '@shared/domain/workspace';
describe('workspace seed', () => {
test('starts empty and seeds the built-in orchestration patterns with a shared timestamp', () => {
const workspace = createWorkspaceSeed();
expect(workspace.projects).toEqual([]);
expect(workspace.sessions).toEqual([]);
expect(workspace.selectedProjectId).toBeUndefined();
expect(workspace.selectedPatternId).toBeUndefined();
expect(workspace.selectedSessionId).toBeUndefined();
expect(workspace.patterns.map((pattern) => pattern.mode)).toEqual([
'single',
'sequential',
'concurrent',
'handoff',
'group-chat',
'magentic',
]);
for (const pattern of workspace.patterns) {
expect(pattern.createdAt).toBe(workspace.lastUpdatedAt);
expect(pattern.updatedAt).toBe(workspace.lastUpdatedAt);
}
const magentic = workspace.patterns.find((pattern) => pattern.mode === 'magentic');
expect(magentic?.availability).toBe('unavailable');
expect(magentic?.unavailabilityReason).toContain('unsupported');
});
});