aura-ai
Version:
AI-powered marketing strategist CLI tool for developers
250 lines (219 loc) • 7.39 kB
JavaScript
import { Command } from 'commander'
import { readFileSync } from 'fs'
import { fileURLToPath } from 'url'
import { dirname, join } from 'path'
import dotenv from 'dotenv'
// Load environment variables
dotenv.config({ path: '.env.local' })
dotenv.config()
// Import command handlers
import { initCommand } from './init/command.js'
import { syncCommand } from './sync/command.js'
import { chatCommand } from './chat/command.js'
import { settingsCommand } from './settings/command.js'
import { addAuraAgentCommand } from './add-aura-agent/command.js'
// Get package.json for version
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
const packageJson = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'))
// Create main program
const program = new Command()
program
.name('aura')
.description('Aura AI - Marketing Intelligence CLI for Developers')
.version(packageJson.version)
.option('-j, --json', 'Output in JSON format for agents')
.option('-q, --quiet', 'Minimal output, no decorations')
.addHelpText('after', `
Examples:
$ aura init --answers "SaaS tool|developers|saves time"
$ aura sync --json
$ aura chat "How to price my product?"
$ aura settings --set-aura "🤖"
$ aura add-aura-agent
For agents: Use --json flag for structured output
For interactive mode: Run 'aura' without commands
For Claude integration: Run 'aura add-aura-agent'`)
// Init command - Product analysis
program
.command('init')
.description('Analyze your product and generate marketing strategy')
.option('-i, --interactive', 'Interactive mode (default)', true)
.option('-a, --answers <answers>', 'Provide all 3 answers separated by |')
.option('-f, --file <path>', 'Read answers from file')
.option('--force', 'Overwrite existing analysis')
.addHelpText('after', `
Examples:
Interactive:
$ aura init
Non-interactive (for agents):
$ aura init --answers "Task management app|Remote teams|Increases productivity by 40%"
JSON output:
$ aura init --answers "answers here" --json
Note: Answers required:
1. Product description (What is your product?)
2. Target audience (Who is it for?)
3. Value proposition (What problem does it solve?)`)
.action(async (options) => {
const globalOpts = program.opts()
await initCommand({ ...options, ...globalOpts })
})
// Sync command - Daily progress report
program
.command('sync')
.description('Generate AI-powered daily progress report from git commits')
.option('--raw', 'Output raw markdown only')
.option('--since <date>', 'Analyze commits since date', 'today')
.option('--copy', 'Auto-copy to clipboard')
.addHelpText('after', `
Examples:
Default report:
$ aura sync
Agent-friendly JSON:
$ aura sync --json
Raw markdown output:
$ aura sync --raw > report.md
Output format (--json):
{
"status": "success",
"data": {
"summary": "Executive summary",
"highlights": ["achievement1", "achievement2"],
"markdown": "Full report in markdown"
}
}`)
.action(async (options) => {
const globalOpts = program.opts()
await syncCommand({ ...options, ...globalOpts })
})
// Chat command - AI marketing consultation
program
.command('chat')
.description('Ask marketing questions to AI strategist')
.argument('[question]', 'Your marketing question')
.option('--context <file>', 'Include additional context from file')
.option('--system <prompt>', 'Override system prompt')
.option('--max-tokens <number>', 'Maximum response tokens', '500')
.option('--stdin', 'Read question from stdin')
.addHelpText('after', `
Examples:
Single question:
$ aura chat "How should I price my SaaS?"
With JSON output:
$ aura chat "Marketing strategy?" --json
From stdin (for piping):
$ echo "How to reach developers?" | aura chat --stdin
Multiple questions from file:
$ cat questions.txt | aura chat --stdin
Output format (--json):
{
"status": "success",
"data": {
"question": "Your question",
"answer": "AI response",
"tokens_used": 245
}
}`)
.action(async (question, options) => {
const globalOpts = program.opts()
await chatCommand(question, { ...options, ...globalOpts })
})
// Settings command - Configuration management
program
.command('settings')
.description('Manage Aura configuration and preferences')
.option('--list', 'Show current settings')
.option('--set-aura <avatar>', 'Set Aura avatar')
.option('--set-user <avatar>', 'Set User avatar')
.option('--reset', 'Reset to defaults')
.addHelpText('after', `
Examples:
View settings:
$ aura settings --list
Change avatars:
$ aura settings --set-aura "🤖" --set-user "👤"
Reset all:
$ aura settings --reset
Agent usage:
$ aura settings --list --json
Output format (--json):
{
"avatars": {
"aura": "🌀",
"user": ">"
}
}`)
.action(async (options) => {
const globalOpts = program.opts()
await settingsCommand({ ...options, ...globalOpts })
})
// Add Aura Agent command - Install agent to Claude
program
.command('add-aura-agent')
.description('Install Aura agent to Claude for @aura commands')
.addHelpText('after', `
This command will:
1. Create ~/.claude/agents/ directory if needed
2. Install aura.md agent file
3. Enable @aura commands in Claude
After installation, you can use in Claude:
@aura sync
@aura help me with marketing
@aura analyze my product
Examples:
$ aura add-aura-agent
$ aura add-aura-agent --json`)
.action(async (options) => {
const globalOpts = program.opts()
await addAuraAgentCommand({ ...options, ...globalOpts })
})
// Help command - Show all available commands
program
.command('help [command]')
.description('Display help for command')
.action((command) => {
if (command) {
const cmd = program.commands.find(c => c.name() === command)
if (cmd) {
cmd.help()
} else {
console.error(`Unknown command: ${command}`)
program.help()
}
} else {
program.help()
}
})
// Error handling for unknown commands
program.on('command:*', () => {
console.error('Invalid command: %s\nSee --help for available commands.', program.args.join(' '))
process.exit(1)
})
// Parse arguments
try {
// Check if running with a command or just flags
const hasCommand = process.argv.slice(2).some(arg =>
!arg.startsWith('-') && ['init', 'sync', 'chat', 'settings', 'help', 'add-aura-agent'].includes(arg)
)
if (process.argv.length === 2 || (!hasCommand && !process.argv.slice(2).includes('--help') && !process.argv.slice(2).includes('-h') && !process.argv.slice(2).includes('--version'))) {
// No command provided, run interactive mode
console.log('Starting interactive mode...')
console.log('Use "aura --help" for CLI commands\n')
// Import and run interactive app
const { default: runInteractive } = await import('./main.jsx')
runInteractive()
} else {
// Has command or help flag, parse normally
await program.parseAsync(process.argv)
}
} catch (error) {
if (program.opts().json) {
console.log(JSON.stringify({
status: 'error',
error: error.message
}))
} else {
console.error('Error:', error.message)
}
process.exit(1)
}