feat(mosaic): drill-down main menu + provider-first flow + quick start
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful

Replace the linear 12-stage wizard interrogation with a menu-driven
architecture. Key changes:

- Main menu with drill-down sections: Quick Start, Providers, Agent
  Identity, Skills, Gateway, Advanced, Finish & Apply
- Quick Start path: 3 questions (API key, admin email, password) with
  sensible defaults for everything else. Target: under 90 seconds.
- Provider-first flow: LLM API key collection moves to the front of
  the wizard, with auto-detection of Anthropic vs OpenAI from key prefix
- Deterministic intent/naming: user picks an intent category (general,
  software-dev, devops, research, content, custom) and gets a thematic
  agent name proposal (Mosaic, Forge, Sentinel, Atlas, Muse)
- Headless backward compat: MOSAIC_ASSUME_YES=1 + env vars still work
  unchanged, with new MOSAIC_AGENT_NAME and MOSAIC_AGENT_INTENT vars
- Version bump: 0.0.26 -> 0.0.27

Closes #438

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jarvis
2026-04-05 19:10:41 -05:00
parent 62b2ce2da1
commit 6deae95339
13 changed files with 1243 additions and 44 deletions

View File

@@ -17,6 +17,7 @@ import { runWizard } from '../../src/wizard.js';
describe('Full Wizard (headless)', () => {
let tmpDir: string;
const repoRoot = join(import.meta.dirname, '..', '..');
const originalEnv = { ...process.env };
beforeEach(() => {
tmpDir = mkdtempSync(join(tmpdir(), 'mosaic-wizard-test-'));
@@ -32,12 +33,16 @@ describe('Full Wizard (headless)', () => {
afterEach(() => {
rmSync(tmpDir, { recursive: true, force: true });
process.env = { ...originalEnv };
});
it('quick start produces valid SOUL.md', async () => {
// The headless path reads agent name from MOSAIC_AGENT_NAME env var
// (via agentIntentStage) rather than prompting interactively.
process.env['MOSAIC_AGENT_NAME'] = 'TestBot';
const prompter = new HeadlessPrompter({
'Installation mode': 'quick',
'What name should agents use?': 'TestBot',
'Communication style': 'direct',
'Your name': 'Tester',
'Your pronouns': 'They/Them',
@@ -62,9 +67,10 @@ describe('Full Wizard (headless)', () => {
});
it('quick start produces valid USER.md', async () => {
process.env['MOSAIC_AGENT_NAME'] = 'TestBot';
const prompter = new HeadlessPrompter({
'Installation mode': 'quick',
'What name should agents use?': 'TestBot',
'Communication style': 'direct',
'Your name': 'Tester',
'Your pronouns': 'He/Him',