fix: make mosaic init idempotent — detect existing config files
- mosaic-init bash script: detect existing SOUL.md/USER.md/TOOLS.md and prompt user to keep, import (re-use values as defaults), or overwrite. Non-interactive mode exits cleanly unless --force is passed. Overwrite creates timestamped backups before replacing files. - launch.ts checkSoul(): prefer 'mosaic wizard' over legacy bash script when SOUL.md is missing, with fallback to mosaic-init. - detect-install.ts: pre-populate wizard state with existing values when user chooses 'reconfigure', so they see current settings as defaults. - soul-setup.ts: show existing agent name and communication style as defaults during reconfiguration. - Added tests for reconfigure pre-population and reset non-population.
This commit is contained in:
@@ -87,7 +87,9 @@ export async function detectInstallStage(
|
||||
],
|
||||
});
|
||||
|
||||
if (state.installAction === 'keep') {
|
||||
if (state.installAction === 'keep' || state.installAction === 'reconfigure') {
|
||||
// Load existing values — for 'keep' they're final, for 'reconfigure'
|
||||
// they become pre-populated defaults so the user can tweak them.
|
||||
state.soul = await config.readSoul();
|
||||
state.user = await config.readUser();
|
||||
state.tools = await config.readTools();
|
||||
|
||||
@@ -24,6 +24,18 @@ export async function soulSetupStage(p: WizardPrompter, state: WizardState): Pro
|
||||
return undefined;
|
||||
},
|
||||
});
|
||||
} else if (state.installAction === 'reconfigure') {
|
||||
// Show existing value as default so the user can accept or change it
|
||||
state.soul.agentName = await p.text({
|
||||
message: 'What name should agents use?',
|
||||
placeholder: state.soul.agentName,
|
||||
defaultValue: state.soul.agentName,
|
||||
validate: (v) => {
|
||||
if (v.length === 0) return 'Name cannot be empty';
|
||||
if (v.length > 50) return 'Name must be under 50 characters';
|
||||
return undefined;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (state.mode === 'advanced') {
|
||||
@@ -38,7 +50,7 @@ export async function soulSetupStage(p: WizardPrompter, state: WizardState): Pro
|
||||
state.soul.roleDescription ??= DEFAULTS.roleDescription;
|
||||
}
|
||||
|
||||
if (!state.soul.communicationStyle) {
|
||||
if (!state.soul.communicationStyle || state.installAction === 'reconfigure') {
|
||||
state.soul.communicationStyle = await p.select<CommunicationStyle>({
|
||||
message: 'Communication style',
|
||||
options: [
|
||||
@@ -46,7 +58,7 @@ export async function soulSetupStage(p: WizardPrompter, state: WizardState): Pro
|
||||
{ value: 'friendly', label: 'Friendly', hint: 'Warm but efficient, conversational' },
|
||||
{ value: 'formal', label: 'Formal', hint: 'Professional, structured, thorough' },
|
||||
],
|
||||
initialValue: 'direct',
|
||||
initialValue: state.soul.communicationStyle ?? 'direct',
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user