Co-authored-by: Jason Woltje <jason@diversecanvas.com> Co-committed-by: Jason Woltje <jason@diversecanvas.com>
110 lines
3.2 KiB
TypeScript
110 lines
3.2 KiB
TypeScript
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
import {
|
|
mkdtempSync,
|
|
mkdirSync,
|
|
writeFileSync,
|
|
readFileSync,
|
|
existsSync,
|
|
rmSync,
|
|
cpSync,
|
|
} from 'node:fs';
|
|
import { join } from 'node:path';
|
|
import { tmpdir } from 'node:os';
|
|
import { HeadlessPrompter } from '../../src/prompter/headless-prompter.js';
|
|
import { createConfigService } from '../../src/config/config-service.js';
|
|
import { runWizard } from '../../src/wizard.js';
|
|
|
|
describe('Full Wizard (headless)', () => {
|
|
let tmpDir: string;
|
|
const repoRoot = join(import.meta.dirname, '..', '..');
|
|
|
|
beforeEach(() => {
|
|
tmpDir = mkdtempSync(join(tmpdir(), 'mosaic-wizard-test-'));
|
|
// Copy templates to tmp dir
|
|
const templatesDir = join(repoRoot, 'templates');
|
|
if (existsSync(templatesDir)) {
|
|
cpSync(templatesDir, join(tmpDir, 'templates'), { recursive: true });
|
|
}
|
|
});
|
|
|
|
afterEach(() => {
|
|
rmSync(tmpDir, { recursive: true, force: true });
|
|
});
|
|
|
|
it('quick start produces valid SOUL.md', async () => {
|
|
const prompter = new HeadlessPrompter({
|
|
'Installation mode': 'quick',
|
|
'What name should agents use?': 'TestBot',
|
|
'Communication style': 'direct',
|
|
'Your name': 'Tester',
|
|
'Your pronouns': 'They/Them',
|
|
'Your timezone': 'UTC',
|
|
});
|
|
|
|
await runWizard({
|
|
mosaicHome: tmpDir,
|
|
sourceDir: tmpDir,
|
|
prompter,
|
|
configService: createConfigService(tmpDir, tmpDir),
|
|
});
|
|
|
|
const soulPath = join(tmpDir, 'SOUL.md');
|
|
expect(existsSync(soulPath)).toBe(true);
|
|
|
|
const soul = readFileSync(soulPath, 'utf-8');
|
|
expect(soul).toContain('You are **TestBot**');
|
|
expect(soul).toContain('Be direct, concise, and concrete');
|
|
expect(soul).toContain('execution partner and visibility engine');
|
|
});
|
|
|
|
it('quick start produces valid USER.md', async () => {
|
|
const prompter = new HeadlessPrompter({
|
|
'Installation mode': 'quick',
|
|
'What name should agents use?': 'TestBot',
|
|
'Communication style': 'direct',
|
|
'Your name': 'Tester',
|
|
'Your pronouns': 'He/Him',
|
|
'Your timezone': 'America/Chicago',
|
|
});
|
|
|
|
await runWizard({
|
|
mosaicHome: tmpDir,
|
|
sourceDir: tmpDir,
|
|
prompter,
|
|
configService: createConfigService(tmpDir, tmpDir),
|
|
});
|
|
|
|
const userPath = join(tmpDir, 'USER.md');
|
|
expect(existsSync(userPath)).toBe(true);
|
|
|
|
const user = readFileSync(userPath, 'utf-8');
|
|
expect(user).toContain('**Name:** Tester');
|
|
expect(user).toContain('**Pronouns:** He/Him');
|
|
expect(user).toContain('**Timezone:** America/Chicago');
|
|
});
|
|
|
|
it('applies CLI overrides', async () => {
|
|
const prompter = new HeadlessPrompter({
|
|
'Installation mode': 'quick',
|
|
'Your name': 'FromPrompt',
|
|
});
|
|
|
|
await runWizard({
|
|
mosaicHome: tmpDir,
|
|
sourceDir: tmpDir,
|
|
prompter,
|
|
configService: createConfigService(tmpDir, tmpDir),
|
|
cliOverrides: {
|
|
soul: {
|
|
agentName: 'FromCLI',
|
|
communicationStyle: 'formal',
|
|
},
|
|
},
|
|
});
|
|
|
|
const soul = readFileSync(join(tmpDir, 'SOUL.md'), 'utf-8');
|
|
expect(soul).toContain('You are **FromCLI**');
|
|
expect(soul).toContain('Use professional, structured language');
|
|
});
|
|
});
|