397777089e
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
67 lines
3.0 KiB
JavaScript
67 lines
3.0 KiB
JavaScript
import { describe, it, expect } from 'vitest';
|
|
import { updateChainProgress, extractSkillInvocations } from './router-stop-gate.mjs';
|
|
|
|
const chains = {
|
|
L1: { name: 'brainstorming chain', sequence: ['brainstorming', 'writing-plans', 'executing-plans'] },
|
|
L13: { name: 'finance chain', sequence: ['billing-audit', 'pest', 'ru-tax-accounting'] },
|
|
};
|
|
|
|
describe('extractSkillInvocations', () => {
|
|
it('extracts skill names from Skill tool invocations', () => {
|
|
const events = [
|
|
{ tool_name: 'Skill', tool_input: { skill: 'brainstorming' } },
|
|
{ tool_name: 'Edit', tool_input: {} },
|
|
{ tool_name: 'Skill', tool_input: { skill: 'writing-plans' } },
|
|
];
|
|
expect(extractSkillInvocations(events)).toEqual(['brainstorming', 'writing-plans']);
|
|
});
|
|
|
|
it('returns empty when no Skill invocations', () => {
|
|
expect(extractSkillInvocations([{ tool_name: 'Edit' }])).toEqual([]);
|
|
});
|
|
|
|
it('strips namespace prefix (superpowers:brainstorming → brainstorming)', () => {
|
|
const events = [{ tool_name: 'Skill', tool_input: { skill: 'superpowers:brainstorming' } }];
|
|
expect(extractSkillInvocations(events)).toEqual(['brainstorming']);
|
|
});
|
|
});
|
|
|
|
describe('updateChainProgress', () => {
|
|
it('appends matched chain step to chainProgress', () => {
|
|
const state = { classification: { recommendedChain: 'L1' }, chainProgress: [] };
|
|
const updated = updateChainProgress(state, ['brainstorming'], chains);
|
|
expect(updated.chainProgress).toEqual(['brainstorming']);
|
|
});
|
|
|
|
it('appends multiple steps if multiple skills invoked', () => {
|
|
const state = { classification: { recommendedChain: 'L1' }, chainProgress: [] };
|
|
const updated = updateChainProgress(state, ['brainstorming', 'writing-plans'], chains);
|
|
expect(updated.chainProgress).toEqual(['brainstorming', 'writing-plans']);
|
|
});
|
|
|
|
it('ignores skills not in chain sequence', () => {
|
|
const state = { classification: { recommendedChain: 'L1' }, chainProgress: [] };
|
|
const updated = updateChainProgress(state, ['random-skill'], chains);
|
|
expect(updated.chainProgress).toEqual([]);
|
|
});
|
|
|
|
it('marks chainCompleted=true when last step reached', () => {
|
|
const state = { classification: { recommendedChain: 'L1' }, chainProgress: ['brainstorming', 'writing-plans'] };
|
|
const updated = updateChainProgress(state, ['executing-plans'], chains);
|
|
expect(updated.chainCompleted).toBe(true);
|
|
});
|
|
|
|
it('preserves existing chainProgress without duplicates', () => {
|
|
const state = { classification: { recommendedChain: 'L1' }, chainProgress: ['brainstorming'] };
|
|
const updated = updateChainProgress(state, ['brainstorming', 'writing-plans'], chains);
|
|
expect(updated.chainProgress).toEqual(['brainstorming', 'writing-plans']);
|
|
});
|
|
});
|
|
|
|
describe('UTF-8 cyrillic stdin (regression — Stage 3 fix 1)', () => {
|
|
it('module loads with UTF-8 helper wired (smoke)', async () => {
|
|
const mod = await import('./router-stop-gate.mjs');
|
|
expect(typeof mod.updateChainProgress).toBe('function');
|
|
});
|
|
});
|