takt/src/__tests__/team-leader-schema-loader.test.ts
nrs a82d6d9d8a
github-issue-244 (#250)
* dist-tag 検証をリトライ付きに変更(npm レジストリの結果整合性対策)

* takt run 実行時に蓋閉じスリープを抑制

* takt: github-issue-244

* takt: #244/implement-parallel-subtasks
2026-02-12 11:51:34 +09:00

106 lines
2.8 KiB
TypeScript

import { describe, it, expect } from 'vitest';
import { join } from 'node:path';
import { PieceMovementRawSchema } from '../core/models/schemas.js';
import { normalizePieceConfig } from '../infra/config/loaders/pieceParser.js';
describe('team_leader schema', () => {
it('max_parts <= 3 の設定を受け付ける', () => {
const raw = {
name: 'implement',
team_leader: {
persona: 'team-leader',
max_parts: 3,
timeout_ms: 120000,
},
instruction_template: 'decompose',
};
const result = PieceMovementRawSchema.safeParse(raw);
expect(result.success).toBe(true);
});
it('max_parts > 3 は拒否する', () => {
const raw = {
name: 'implement',
team_leader: {
max_parts: 4,
},
instruction_template: 'decompose',
};
const result = PieceMovementRawSchema.safeParse(raw);
expect(result.success).toBe(false);
});
it('parallel と team_leader の同時指定は拒否する', () => {
const raw = {
name: 'implement',
parallel: [{ name: 'sub', instruction_template: 'x' }],
team_leader: {
max_parts: 2,
},
instruction_template: 'decompose',
};
const result = PieceMovementRawSchema.safeParse(raw);
expect(result.success).toBe(false);
});
it('arpeggio と team_leader の同時指定は拒否する', () => {
const raw = {
name: 'implement',
arpeggio: {
source: 'csv',
source_path: './data.csv',
template: './prompt.md',
},
team_leader: {
max_parts: 2,
},
instruction_template: 'decompose',
};
const result = PieceMovementRawSchema.safeParse(raw);
expect(result.success).toBe(false);
});
});
describe('normalizePieceConfig team_leader', () => {
it('team_leader を内部形式へ正規化する', () => {
const pieceDir = join(process.cwd(), 'src', '__tests__');
const raw = {
name: 'piece',
movements: [
{
name: 'implement',
team_leader: {
persona: 'team-leader',
max_parts: 2,
timeout_ms: 90000,
part_persona: 'coder',
part_allowed_tools: ['Read', 'Edit'],
part_edit: true,
part_permission_mode: 'edit',
},
instruction_template: 'decompose',
},
],
};
const config = normalizePieceConfig(raw, pieceDir);
const movement = config.movements[0];
expect(movement).toBeDefined();
expect(movement!.teamLeader).toEqual({
persona: 'team-leader',
personaPath: undefined,
maxParts: 2,
timeoutMs: 90000,
partPersona: 'coder',
partPersonaPath: undefined,
partAllowedTools: ['Read', 'Edit'],
partEdit: true,
partPermissionMode: 'edit',
});
});
});