Commands API
Reference for command class structure and implementation in ao-forge.
Overview
ao-forge uses a command-based architecture where each CLI command is implemented as a class with specific methods and options. This document provides a comprehensive reference for all command classes.
Base Command Class
All commands extend from the base Command
class:
abstract class Command {
abstract name: string
abstract description: string
abstract options: CommandOption[]
abstract execute(args: string[], options: Record<string, any>): Promise<void>
protected validateArgs(args: string[]): boolean
protected validateOptions(options: Record<string, any>): boolean
protected showHelp(): void
protected showError(message: string): void
}
interface CommandOption {
name: string
alias?: string
description: string
type: 'string' | 'boolean' | 'number'
required?: boolean
default?: any
}
Init Command
Creates a new ao-forge project.
class InitCommand extends Command {
name = 'init'
description = 'Create a new AO-powered application'
options: CommandOption[] = [
{
name: 'framework',
alias: 'f',
description: 'Framework to use (nextjs, nuxtjs)',
type: 'string'
},
{
name: 'package-manager',
alias: 'p',
description: 'Package manager (npm, pnpm, yarn)',
type: 'string',
default: 'pnpm'
},
{
name: 'template',
alias: 't',
description: 'Template to use',
type: 'string',
default: 'default'
},
{
name: 'path',
description: 'Path to create project',
type: 'string'
},
{
name: 'skip-install',
description: 'Skip package installation',
type: 'boolean',
default: false
},
{
name: 'force',
description: 'Overwrite existing files',
type: 'boolean',
default: false
}
]
async execute(args: string[], options: Record<string, any>): Promise<void> {
const projectName = args[0]
if (!projectName) {
this.showError('Project name is required')
return
}
const projectManager = new ProjectManager()
await projectManager.createProject({
name: projectName,
framework: options.framework,
packageManager: options['package-manager'],
template: options.template,
path: options.path,
skipInstall: options['skip-install'],
force: options.force
})
}
}
Dev Command
Starts the development server.
class DevCommand extends Command {
name = 'dev'
description = 'Start the development server'
options: CommandOption[] = [
{
name: 'port',
description: 'Port for development server',
type: 'number',
default: 3000
},
{
name: 'host',
description: 'Host for development server',
type: 'string',
default: 'localhost'
},
{
name: 'open',
description: 'Open browser automatically',
type: 'boolean',
default: false
},
{
name: 'framework',
description: 'Framework to use',
type: 'string'
},
{
name: 'process',
description: 'Start specific AO process',
type: 'string'
},
{
name: 'monitor',
description: 'Enable process monitoring',
type: 'boolean',
default: false
},
{
name: 'debug',
description: 'Enable debug mode',
type: 'boolean',
default: false
},
{
name: 'verbose',
description: 'Verbose logging',
type: 'boolean',
default: false
}
]
async execute(args: string[], options: Record<string, any>): Promise<void> {
const devServer = new DevServer({
port: options.port,
host: options.host,
open: options.open,
framework: options.framework,
process: options.process,
monitor: options.monitor,
debug: options.debug,
verbose: options.verbose
})
await devServer.start()
}
}
AI Command
Generates code using AI.
class AICommand extends Command {
name = 'ai'
description = 'Generate code using AI'
options: CommandOption[] = [
{
name: 'model',
description: 'AI model to use',
type: 'string',
default: 'gpt-4'
},
{
name: 'output',
description: 'Output directory',
type: 'string',
default: './ao/'
},
{
name: 'include-docs',
description: 'Include documentation',
type: 'boolean',
default: false
},
{
name: 'generate-types',
description: 'Generate TypeScript types',
type: 'boolean',
default: false
},
{
name: 'prompt',
description: 'Custom prompt',
type: 'string'
},
{
name: 'prompt-file',
description: 'Prompt from file',
type: 'string'
}
]
async execute(args: string[], options: Record<string, any>): Promise<void> {
const subcommand = args[0]
const name = args[1]
const description = args[2]
if (!subcommand || !name || !description) {
this.showError('Usage: ao-forge ai generate <type> <name> <description>')
return
}
const aiManager = new AIManager()
const result = await aiManager.generate({
type: subcommand,
name: name,
description: description,
model: options.model,
output: options.output,
includeDocs: options['include-docs'],
generateTypes: options['generate-types'],
prompt: options.prompt,
promptFile: options['prompt-file']
})
if (result.success) {
console.log('Code generated successfully!')
} else {
this.showError(result.error || 'Code generation failed')
}
}
}
Build Command
Builds the project for production.
class BuildCommand extends Command {
name = 'build'
description = 'Build the project for production'
options: CommandOption[] = [
{
name: 'framework',
description: 'Framework to use',
type: 'string'
},
{
name: 'output',
description: 'Output directory',
type: 'string',
default: './dist'
},
{
name: 'optimize',
description: 'Enable optimization',
type: 'boolean',
default: true
},
{
name: 'source-maps',
description: 'Generate source maps',
type: 'boolean',
default: false
},
{
name: 'minify',
description: 'Minify assets',
type: 'boolean',
default: true
},
{
name: 'static',
description: 'Build for static hosting',
type: 'boolean',
default: false
},
{
name: 'server',
description: 'Build for server deployment',
type: 'boolean',
default: false
},
{
name: 'process',
description: 'Build AO processes',
type: 'boolean',
default: true
},
{
name: 'deploy',
description: 'Deploy after build',
type: 'boolean',
default: false
},
{
name: 'platform',
description: 'Deployment platform',
type: 'string'
},
{
name: 'env',
description: 'Build environment',
type: 'string',
default: 'production'
}
]
async execute(args: string[], options: Record<string, any>): Promise<void> {
const buildManager = new BuildManager()
const result = await buildManager.build({
framework: options.framework,
output: options.output,
optimize: options.optimize,
sourceMaps: options['source-maps'],
minify: options.minify,
static: options.static,
server: options.server,
process: options.process,
env: options.env
})
if (result.success) {
console.log('Build completed successfully!')
if (options.deploy) {
const deployManager = new DeploymentManager()
await deployManager.deploy({
platform: options.platform,
environment: options.env
})
}
} else {
this.showError('Build failed: ' + result.errors.join(', '))
}
}
}
Config Command
Manages configuration settings.
class ConfigCommand extends Command {
name = 'config'
description = 'Manage configuration settings'
options: CommandOption[] = [
{
name: 'file',
description: 'Configuration file path',
type: 'string',
default: './ao.config.yml'
},
{
name: 'format',
description: 'Output format (json, yaml)',
type: 'string',
default: 'yaml'
}
]
async execute(args: string[], options: Record<string, any>): Promise<void> {
const subcommand = args[0]
const key = args[1]
const value = args[2]
const configManager = new ConfigManager()
switch (subcommand) {
case 'get':
if (!key) {
this.showError('Key is required for get command')
return
}
const configValue = await configManager.get(key, options.file)
console.log(configValue)
break
case 'set':
if (!key || !value) {
this.showError('Key and value are required for set command')
return
}
await configManager.set(key, value, options.file)
console.log('Configuration updated')
break
case 'list':
const config = await configManager.list(options.file)
console.log(JSON.stringify(config, null, 2))
break
case 'validate':
const validation = await configManager.validate(options.file)
if (validation.valid) {
console.log('Configuration is valid')
} else {
this.showError('Configuration validation failed: ' + validation.errors.join(', '))
}
break
case 'reset':
await configManager.reset(options.file)
console.log('Configuration reset to defaults')
break
default:
this.showError('Unknown subcommand: ' + subcommand)
}
}
}
Process Command
Manages AO processes.
class ProcessCommand extends Command {
name = 'process'
description = 'Manage AO processes'
options: CommandOption[] = [
{
name: 'wallet',
description: 'Wallet file path',
type: 'string'
},
{
name: 'module',
description: 'Module ID',
type: 'string'
},
{
name: 'cron',
description: 'Cron schedule',
type: 'string'
},
{
name: 'sqlite',
description: 'Use SQLite module',
type: 'boolean',
default: false
},
{
name: 'monitor',
description: 'Enable monitoring',
type: 'boolean',
default: false
}
]
async execute(args: string[], options: Record<string, any>): Promise<void> {
const subcommand = args[0]
const processName = args[1]
const processManager = new ProcessManager()
switch (subcommand) {
case 'start':
await processManager.startProcess({
name: processName,
wallet: options.wallet,
module: options.module,
cron: options.cron,
sqlite: options.sqlite,
monitor: options.monitor
})
console.log('Process started successfully')
break
case 'stop':
await processManager.stopProcess(processName)
console.log('Process stopped successfully')
break
case 'restart':
await processManager.restartProcess(processName)
console.log('Process restarted successfully')
break
case 'list':
const processes = await processManager.listProcesses()
console.table(processes)
break
case 'status':
const status = await processManager.getStatus(processName)
console.log('Status:', status)
break
case 'monitor':
await processManager.monitorProcess(processName)
break
default:
this.showError('Unknown subcommand: ' + subcommand)
}
}
}
Version Command
Displays version information.
class VersionCommand extends Command {
name = 'version'
description = 'Display version information'
options: CommandOption[] = [
{
name: 'verbose',
description: 'Show detailed version information',
type: 'boolean',
default: false
},
{
name: 'json',
description: 'Output in JSON format',
type: 'boolean',
default: false
}
]
async execute(args: string[], options: Record<string, any>): Promise<void> {
const versionInfo = await this.getVersionInfo(options.verbose)
if (options.json) {
console.log(JSON.stringify(versionInfo, null, 2))
} else {
this.displayVersion(versionInfo)
}
}
private async getVersionInfo(verbose: boolean): Promise<VersionInfo> {
const packageJson = await this.loadPackageJson()
return {
aoForge: packageJson.version,
node: process.version,
npm: await this.getNpmVersion(),
aos: await this.getAOSVersion(),
framework: await this.getFrameworkVersion(),
packageManager: await this.getPackageManagerVersion()
}
}
private displayVersion(info: VersionInfo): void {
console.log(`ao-forge: ${info.aoForge}`)
console.log(`Node.js: ${info.node}`)
console.log(`npm: ${info.npm}`)
if (info.aos) {
console.log(`AOS CLI: ${info.aos}`)
}
if (info.framework) {
console.log(`Framework: ${info.framework}`)
}
if (info.packageManager) {
console.log(`Package Manager: ${info.packageManager}`)
}
}
}
interface VersionInfo {
aoForge: string
node: string
npm: string
aos?: string
framework?: string
packageManager?: string
}
Command Registry
Commands are registered in the main CLI application:
class CLI {
private commands: Map<string, Command> = new Map()
constructor() {
this.registerCommands()
}
private registerCommands(): void {
this.commands.set('init', new InitCommand())
this.commands.set('dev', new DevCommand())
this.commands.set('ai', new AICommand())
this.commands.set('build', new BuildCommand())
this.commands.set('config', new ConfigCommand())
this.commands.set('process', new ProcessCommand())
this.commands.set('version', new VersionCommand())
}
async execute(args: string[]): Promise<void> {
const commandName = args[0]
const command = this.commands.get(commandName)
if (!command) {
console.error(`Unknown command: ${commandName}`)
this.showHelp()
return
}
const { options, remainingArgs } = this.parseOptions(args.slice(1), command.options)
await command.execute(remainingArgs, options)
}
}
Best Practices
- Command Design - Keep commands focused and single-purpose
- Option Validation - Validate all options and arguments
- Error Handling - Provide clear error messages
- Help Text - Include comprehensive help information
- Testing - Write tests for all commands
Related
- Configuration API - Configuration file reference
- Managers API - Manager classes
- Types API - TypeScript interfaces