Merge pull request #115 from Lifeforge-app/fix/forgecli

(ForgeCLI) Include flags for host exposure and manually specify client port for dev mode
This commit is contained in:
Melvin Chia
2026-03-25 15:02:23 +08:00
committed by GitHub
5 changed files with 72 additions and 20 deletions

View File

@@ -3,15 +3,15 @@ import { Command } from 'commander'
import logger from '@/utils/logger'
const LOGO = `
╭─────────────────────────────────────╮
${chalk.bold.cyan('F O R G E')} ${chalk.dim('C L I')} ⚡ │
${chalk.dim('Build & Manage LifeForge')}
╰─────────────────────────────────────╯
`
const LOGO = chalk.bold.green(`
██╗ ██╗███████╗███████╗███████╗ ██████╗ ██████╗ ██████╗ ███████╗
██║ ██║██╔════╝██╔════╝██╔════╝██╔═══██╗██╔══██╗██╔════╝ ██╔════╝
██║ ██║█████╗ █████╗ █████╗ ██║ ██║██████╔╝██║ ███╗█████╗
██║ ██║██╔══╝ ██╔══╝ ██╔══╝ ██║ ██║██╔══██╗██║ ██║██╔══╝
███████╗██║██║ ███████╗██║ ╚██████╔╝██║ ██║╚██████╔╝███████╗
╚══════╝╚═╝╚═╝ ╚══════╝╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚══════╝
`)
const SECTION_ICONS: Record<string, string> = {
Commands: '📦',

View File

@@ -41,6 +41,11 @@ export function setupCLI(): void {
`Set log level (${LOG_LEVELS.join(', ')})`,
'info'
)
.option('--host', 'Expose frontend client on the local network')
.option(
'--port <port>',
'Specify the port for the client dev server (default: 5173)'
)
.hook('preAction', (thisCommand, actionCommand) => {
const level = thisCommand.opts().logLevel as (typeof LOG_LEVELS)[number]

View File

@@ -12,9 +12,10 @@ interface ConcurrentServiceConfig<T extends string | (() => string) = string> {
/**
* Creates service configurations for concurrent execution
*/
export default async function getConcurrentServices(): Promise<
ConcurrentServiceConfig[]
> {
export default async function getConcurrentServices(
host?: boolean,
port?: string
): Promise<ConcurrentServiceConfig[]> {
const SERVICES_TO_START = ['db', 'server', 'client']
const concurrentServices: ConcurrentServiceConfig[] = []
@@ -33,9 +34,28 @@ export default async function getConcurrentServices(): Promise<
getEnvVars(config.requiresEnv)
}
// Add --host and --port flags for client service if provided
let finalCommand = command
if (service === 'client') {
const args = []
if (host) {
args.push('--host')
}
if (port) {
args.push('--port', port)
}
if (args.length > 0) {
finalCommand = `${command} ${args.join(' ')}`
}
}
concurrentServices.push({
name: service,
command,
command: finalCommand,
cwd
})
}

View File

@@ -14,7 +14,9 @@ import getConcurrentServices from './getConcurrentServices'
*/
export async function startSingleService(
service: string,
extraArgs: string[] = []
extraArgs: string[] = [],
host?: boolean,
port?: string
): Promise<void> {
// Handle core services
if (service in SERVICE_COMMANDS) {
@@ -33,7 +35,18 @@ export async function startSingleService(
logger.debug(`Current Working Directory: ${chalk.blue(cwd)}`)
executeCommand(command, { cwd, stdio: 'inherit' }, extraArgs)
// Add --host and --port flags for client service if provided
const finalExtraArgs = [...extraArgs]
if (service === 'client') {
if (host) {
finalExtraArgs.push('--host')
}
if (port) {
finalExtraArgs.push('--port', port)
}
}
executeCommand(command, { cwd, stdio: 'inherit' }, finalExtraArgs)
return
}
@@ -53,9 +66,12 @@ export async function startSingleService(
/**
* Starts all development services concurrently
*/
export async function startAllServices(): Promise<void> {
export async function startAllServices(
host?: boolean,
port?: string
): Promise<void> {
try {
const concurrentServices = await getConcurrentServices()
const concurrentServices = await getConcurrentServices(host, port)
const { result } = concurrently(concurrentServices, {
killOthersOn: ['failure', 'success'],

View File

@@ -1,4 +1,5 @@
import chalk from 'chalk'
import type { Command } from 'commander'
import logger from '@/utils/logger'
@@ -8,10 +9,20 @@ import {
startSingleService
} from '../functions/startServices'
export function devHandler(service: string, extraArgs: string[] = []): void {
export function devHandler(
this: Command,
service: string,
extraArgs: string[] = []
): void {
const options = this.parent?.opts()
const host = options?.host
const port = options?.port
if (!service) {
logger.info('Starting all services...')
startAllServices()
startAllServices(host, port)
return
}
@@ -28,7 +39,7 @@ export function devHandler(service: string, extraArgs: string[] = []): void {
}
try {
startSingleService(service, extraArgs)
startSingleService(service, extraArgs, host, port)
} catch (error) {
logger.error(`Failed to start ${chalk.blue(service)} service`)
logger.debug(`Error details: ${error}`)