import { writeFileSync } from 'node:fs'; import { join } from 'node:path'; import { Command } from 'commander'; import pc from 'picocolors'; import { ConfigSchema, type Config } from '../config/types.ts'; import { ensureWorkspace, resolvePath, checkWorkspaceEmpty, syncTemplates } from './utils.ts'; export function onboardCommand(program: Command): void { program .command('onboard [path]') .description('Initialize a new nanobot workspace with config and templates') .action(async (rawPath?: string) => { try { const targetPath = resolvePath(rawPath ?? '~/.config/nanobot'); const configPath = join(targetPath, 'config.json'); console.info(pc.blue('Initializing nanobot workspace...')); console.info(pc.dim(`Target path: ${targetPath}`)); // Check if directory exists and is not empty checkWorkspaceEmpty(targetPath); // Create workspace directory ensureWorkspace(targetPath); console.info(pc.green('✓ Created workspace directory')); // Write default config const defaultConfig: Config = ConfigSchema.parse({}); writeFileSync(configPath, JSON.stringify(defaultConfig, null, 2), 'utf8'); console.info(pc.green('✓ Created config.json')); // Sync templates const createdFiles = syncTemplates(targetPath); for (const file of createdFiles) { console.info(pc.dim(` Created ${file}`)); } console.info(); console.info(pc.green('nanobot workspace initialized successfully!')); console.info(); console.info(pc.bold('Next steps:')); console.info(` 1. Edit ${pc.cyan(configPath)} to add your API keys`); console.info(` 2. Customize ${pc.cyan(join(targetPath, 'USER.md'))} with your preferences`); console.info(` 3. Start chatting: ${pc.cyan('bun run nanobot agent')}`); console.info(); console.info(pc.dim('For Mattermost integration, configure the channels.mattermost section in config.json')); } catch (err) { console.error(pc.red(String(err))); process.exit(1); } }); }