UNPKG

create-eddie

Version:

Create Eddie documentation projects

384 lines (309 loc) 10.3 kB
#!/usr/bin/env node import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; import { execSync } from 'child_process'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); function createEddieProject(projectName) { const currentDir = process.cwd(); const projectDir = path.join(currentDir, projectName); console.log(`\n📝 Creating Eddie project: ${projectName}\n`); // Check if directory already exists if (fs.existsSync(projectDir)) { console.error(`❌ Error: Directory "${projectName}" already exists`); process.exit(1); } // Create project directory fs.mkdirSync(projectDir); // Create directory structure console.log('📁 Creating directory structure...'); const dirs = [ 'edit/0.prompt🤖', 'edit/1.source📦', 'edit/2.sampling✂️', 'edit/3.plot📋', 'edit/4.publish📚', 'edit/4.publish📚/.vitepress/theme', 'edit/archive🗑️', '.system/site-config', '.system/claude', '.system/vector-data' ]; dirs.forEach(dir => { fs.mkdirSync(path.join(projectDir, dir), { recursive: true }); }); // Create package.json console.log('📦 Creating package.json...'); const packageJson = { name: projectName, version: '1.0.0', type: 'module', description: `${projectName} documentation powered by Eddie`, scripts: { 'generate-sidebar': 'node .system/site-config/generate-sidebar.js', dev: 'npm run generate-sidebar && vitepress dev edit/4.publish📚', build: 'npm run generate-sidebar && vitepress build edit/4.publish📚', preview: 'vitepress preview edit/4.publish📚', search: 'eddie-search', reindex: 'eddie-reindex' }, dependencies: { 'eddie-vector-search': '^1.0.0', vitepress: '^1.0.0' } }; fs.writeFileSync( path.join(projectDir, 'package.json'), JSON.stringify(packageJson, null, 2) ); // Create .gitignore console.log('🚫 Creating .gitignore...'); const gitignore = `node_modules/ .DS_Store *.log .env # VitePress .vitepress/dist/ .vitepress/cache/ # Vector search data .system/vector-data/ `; fs.writeFileSync(path.join(projectDir, '.gitignore'), gitignore); // Create .env.example console.log('🔐 Creating .env.example...'); fs.writeFileSync( path.join(projectDir, '.env.example'), 'OPENAI_API_KEY=your_openai_api_key_here\n' ); // Copy VitePress config from template console.log('⚙️ Creating VitePress config...'); const configTemplatePath = path.join(__dirname, 'templates/config.js'); let configContent = fs.readFileSync(configTemplatePath, 'utf-8'); // Replace PROJECT_NAME placeholder configContent = configContent.replace(/PROJECT_NAME/g, projectName); fs.writeFileSync( path.join(projectDir, '.system/site-config/config.js'), configContent ); // Copy theme files console.log('🎨 Creating theme files...'); const themeIndexPath = path.join(__dirname, 'templates/theme-index.js'); const customCssPath = path.join(__dirname, 'templates/custom.css'); fs.copyFileSync( themeIndexPath, path.join(projectDir, 'edit/4.publish📚/.vitepress/theme/index.js') ); fs.copyFileSync( customCssPath, path.join(projectDir, 'edit/4.publish📚/.vitepress/theme/custom.css') ); // Copy generate-sidebar.js console.log('📋 Creating sidebar generator...'); const generateSidebarPath = path.join(__dirname, 'templates/generate-sidebar.js'); fs.copyFileSync( generateSidebarPath, path.join(projectDir, '.system/site-config/generate-sidebar.js') ); // Copy sidebar-order.json template const sidebarOrderPath = path.join(__dirname, 'templates/sidebar-order.json'); fs.copyFileSync( sidebarOrderPath, path.join(projectDir, 'edit/4.publish📚/sidebar-order.json') ); // Copy Claude Code settings and guide console.log('🤖 Setting up Claude Code integration...'); const claudeSettingsPath = path.join(__dirname, 'templates/claude-settings.json'); const eddieGuidePath = path.join(__dirname, 'templates/EDDIE_GUIDE.md'); fs.copyFileSync( claudeSettingsPath, path.join(projectDir, '.system/claude/settings.local.json') ); fs.copyFileSync( eddieGuidePath, path.join(projectDir, '.system/claude/EDDIE_GUIDE.md') ); // Copy prompt templates console.log('📝 Creating prompt templates...'); const promptsDir = path.join(__dirname, 'templates/prompts'); if (fs.existsSync(promptsDir)) { const promptFiles = fs.readdirSync(promptsDir); promptFiles.forEach(file => { if (file.endsWith('.md')) { fs.copyFileSync( path.join(promptsDir, file), path.join(projectDir, 'edit/0.prompt🤖', file) ); } }); } // Create VitePress config symlink const configSymlink = path.join(projectDir, 'edit/4.publish📚/.vitepress/config.js'); const configTarget = '../../../.system/site-config/config.js'; fs.symlinkSync(configTarget, configSymlink); // Create index.md console.log('📄 Creating index.md...'); const indexMd = `# ${projectName} Welcome to your Eddie documentation project! ## Getting Started Start writing your documentation in \`edit/4.publish📚/\`. ## Workflow \`\`\` 0.prompt🤖 → Get AI prompt templates 1.source📦 → Store raw materials 2.sampling✂️ → Extract and refine 3.plot📋 → Create outlines 4.publish📚 → Write final docs → Web archive🗑️ → Archive unused \`\`\` ## Commands \`\`\`bash npm run dev # Start dev server npm run build # Build site npm run search # Vector search npm run reindex # Re-index docs \`\`\` `; fs.writeFileSync(path.join(projectDir, 'edit/4.publish📚/index.md'), indexMd); // Initialize empty vector store console.log('🔍 Initializing vector store...'); fs.writeFileSync(path.join(projectDir, '.system/vector-data/vector_store.json'), '[]'); // Create README.md console.log('📚 Creating README.md...'); const readme = `# ${projectName} Documentation project powered by [Eddie](https://github.com/yourname/eddie) ## Setup ### 1. Install dependencies \`\`\`bash cd ${projectName} npm install \`\`\` ### 2. Configure environment \`\`\`bash cp .env.example .env \`\`\` Add your OpenAI API key to \`.env\`: \`\`\` OPENAI_API_KEY=sk-... \`\`\` ### 3. Open with Obsidian 1. Launch Obsidian 2. Click "Open folder as vault" 3. Select this project folder (\`${projectName}\`) ### 4. Open with VS Code \`\`\`bash code . \`\`\` Launch Claude Code to start writing! ## Workflow \`\`\` 0.prompt🤖 → Use AI prompt templates 1.source📦 → Store raw materials (transcripts, notes) 2.sampling✂️ → Extract and refine content 3.plot📋 → Create document outlines 4.publish📚 → Write final documents → Deployed as website archive🗑️ → Archive unused materials \`\`\` ## Commands \`\`\`bash # Development npm run dev # Start VitePress dev server (http://localhost:5173) # Build npm run build # Build static site (.vitepress/dist/) npm run preview # Preview built site # Vector Search npm run search "your query" # Semantic search across documents npm run reindex # Re-index all documents # Example npm run search "design principles" \`\`\` ## Deployment ### Vercel 1. Push to GitHub \`\`\`bash git init git add . git commit -m "Initial commit" gh repo create git push origin main \`\`\` 2. Deploy to Vercel \`\`\`bash npm install -g vercel vercel \`\`\` ## Documentation Structure Write your documentation in \`edit/4.publish📚/\`: - Markdown files (.md) become web pages - Organize with folders for nested navigation - Use relative links between documents ### Sidebar Configuration The sidebar is automatically generated from \`edit/4.publish📚/sidebar-order.json\`. **To add a new page to the sidebar:** 1. Create your markdown file in \`edit/4.publish📚/\` \`\`\`bash # Example: create new-feature.md \`\`\` 2. Edit \`edit/4.publish📚/sidebar-order.json\` to add the new page: \`\`\`json { "groups": [ { "text": "Getting Started", "items": [ { "file": "index", "text": "Introduction" }, { "file": "new-feature", "text": "New Feature" } ] } ] } \`\`\` 3. Restart dev server (or rebuild): \`\`\`bash npm run dev \`\`\` **For Claude Code users:** When asked to add a new documentation page, Claude should: 1. Create the \`.md\` file in \`edit/4.publish📚/\` 2. Add an entry to \`sidebar-order.json\` with the appropriate file name and display text 3. The sidebar will be automatically regenerated on next build/dev ## Powered by - [Eddie](https://github.com/yourname/eddie) - Documentation framework - [VitePress](https://vitepress.dev/) - Static site generator - [Obsidian](https://obsidian.md/) - Markdown editor - [Claude Code](https://claude.com/claude-code) - AI assistant - [OpenAI Embeddings](https://platform.openai.com/) - Vector search `; fs.writeFileSync(path.join(projectDir, 'README.md'), readme); // Install dependencies console.log('\n📥 Installing dependencies...'); try { execSync('npm install', { cwd: projectDir, stdio: 'inherit' }); } catch (error) { console.error('❌ Failed to install dependencies'); process.exit(1); } // Success message console.log(`\n✅ ${projectName} created successfully!\n`); console.log('Next steps:\n'); console.log(` 1. cd ${projectName}`); console.log(` 2. cp .env.example .env`); console.log(` 3. Add your OPENAI_API_KEY to .env`); console.log(` 4. npm run dev\n`); console.log('To open with Obsidian:'); console.log(` - Obsidian → Open folder as vault → Select "${projectName}"\n`); console.log('Happy documenting! 📝\n'); } // Parse command line arguments const projectName = process.argv[2]; if (!projectName) { console.log('Usage: npx create-eddie <project-name>'); console.log('\nExample:'); console.log(' npx create-eddie my-docs'); process.exit(1); } // Validate project name if (!/^[a-z0-9-_]+$/i.test(projectName)) { console.error('❌ Error: Project name can only contain letters, numbers, hyphens, and underscores'); process.exit(1); } createEddieProject(projectName);