refactor(cli): rename ps to ls and add top-level agent commands
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
import { Command } from 'commander'
|
||||
import { runLsCommand } from './ls.js'
|
||||
import { runModelsCommand } from './models.js'
|
||||
import { withOutput } from '../../output/index.js'
|
||||
|
||||
export function createProviderCommand(): Command {
|
||||
const provider = new Command('provider').description('Manage agent providers')
|
||||
|
||||
provider
|
||||
.command('ls')
|
||||
.description('List available providers and status')
|
||||
.option('--json', 'Output in JSON format')
|
||||
.option('--host <host>', 'Daemon host:port (default: localhost:6767)')
|
||||
.action((options, command) => {
|
||||
if (options.json) {
|
||||
command.parent.parent.opts().format = 'json'
|
||||
}
|
||||
return withOutput(runLsCommand)(options, command)
|
||||
})
|
||||
|
||||
provider
|
||||
.command('models')
|
||||
.description('List models for a provider')
|
||||
.argument('<provider>', 'Provider name (claude, codex, opencode)')
|
||||
.option('--json', 'Output in JSON format')
|
||||
.option('--host <host>', 'Daemon host:port (default: localhost:6767)')
|
||||
.action((provider, options, command) => {
|
||||
if (options.json) {
|
||||
command.parent.parent.opts().format = 'json'
|
||||
}
|
||||
return withOutput(runModelsCommand)(provider, options, command)
|
||||
})
|
||||
|
||||
return provider
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
import type { Command } from 'commander'
|
||||
import type { CommandOptions, ListResult, OutputSchema } from '../../output/index.js'
|
||||
|
||||
/** Provider list item for display */
|
||||
export interface ProviderListItem {
|
||||
provider: string
|
||||
status: string
|
||||
defaultMode: string
|
||||
modes: string
|
||||
}
|
||||
|
||||
/** Static provider data - providers are built-in and don't require daemon */
|
||||
const PROVIDERS: ProviderListItem[] = [
|
||||
{
|
||||
provider: 'claude',
|
||||
status: 'available',
|
||||
defaultMode: 'default',
|
||||
modes: 'plan, default, bypass',
|
||||
},
|
||||
{
|
||||
provider: 'codex',
|
||||
status: 'available',
|
||||
defaultMode: 'auto',
|
||||
modes: 'read-only, auto, full-access',
|
||||
},
|
||||
{
|
||||
provider: 'opencode',
|
||||
status: 'available',
|
||||
defaultMode: 'default',
|
||||
modes: 'plan, default, bypass',
|
||||
},
|
||||
]
|
||||
|
||||
/** Schema for provider ls output */
|
||||
export const providerLsSchema: OutputSchema<ProviderListItem> = {
|
||||
idField: 'provider',
|
||||
columns: [
|
||||
{ header: 'PROVIDER', field: 'provider', width: 12 },
|
||||
{
|
||||
header: 'STATUS',
|
||||
field: 'status',
|
||||
width: 12,
|
||||
color: (value) => {
|
||||
if (value === 'available') return 'green'
|
||||
if (value === 'unavailable') return 'red'
|
||||
return undefined
|
||||
},
|
||||
},
|
||||
{ header: 'DEFAULT MODE', field: 'defaultMode', width: 14 },
|
||||
{ header: 'MODES', field: 'modes', width: 30 },
|
||||
],
|
||||
}
|
||||
|
||||
export type ProviderLsResult = ListResult<ProviderListItem>
|
||||
|
||||
export interface ProviderLsOptions extends CommandOptions {
|
||||
host?: string
|
||||
}
|
||||
|
||||
export async function runLsCommand(
|
||||
_options: ProviderLsOptions,
|
||||
_command: Command
|
||||
): Promise<ProviderLsResult> {
|
||||
// Provider data is static - no daemon connection needed
|
||||
return {
|
||||
type: 'list',
|
||||
data: PROVIDERS,
|
||||
schema: providerLsSchema,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
import type { Command } from 'commander'
|
||||
import type { CommandOptions, ListResult, OutputSchema, CommandError } from '../../output/index.js'
|
||||
|
||||
/** Model list item for display */
|
||||
export interface ModelListItem {
|
||||
model: string
|
||||
id: string
|
||||
}
|
||||
|
||||
/** Static model data by provider */
|
||||
const MODELS_BY_PROVIDER: Record<string, ModelListItem[]> = {
|
||||
claude: [
|
||||
{ model: 'Claude Sonnet 4', id: 'claude-sonnet-4-20250514' },
|
||||
{ model: 'Claude Opus 4', id: 'claude-opus-4-20250514' },
|
||||
{ model: 'Claude Haiku 3.5', id: 'claude-3-5-haiku-20241022' },
|
||||
],
|
||||
codex: [
|
||||
{ model: 'o3-mini', id: 'o3-mini' },
|
||||
{ model: 'o4-mini', id: 'o4-mini' },
|
||||
],
|
||||
opencode: [
|
||||
// opencode uses claude or codex under the hood
|
||||
{ model: 'Claude Sonnet 4', id: 'claude-sonnet-4-20250514' },
|
||||
{ model: 'Claude Opus 4', id: 'claude-opus-4-20250514' },
|
||||
{ model: 'Claude Haiku 3.5', id: 'claude-3-5-haiku-20241022' },
|
||||
{ model: 'o3-mini', id: 'o3-mini' },
|
||||
{ model: 'o4-mini', id: 'o4-mini' },
|
||||
],
|
||||
}
|
||||
|
||||
/** Schema for provider models output */
|
||||
export const providerModelsSchema: OutputSchema<ModelListItem> = {
|
||||
idField: 'id',
|
||||
columns: [
|
||||
{ header: 'MODEL', field: 'model', width: 30 },
|
||||
{ header: 'ID', field: 'id', width: 30 },
|
||||
],
|
||||
}
|
||||
|
||||
export type ProviderModelsResult = ListResult<ModelListItem>
|
||||
|
||||
export interface ProviderModelsOptions extends CommandOptions {
|
||||
host?: string
|
||||
}
|
||||
|
||||
export async function runModelsCommand(
|
||||
provider: string,
|
||||
_options: ProviderModelsOptions,
|
||||
_command: Command
|
||||
): Promise<ProviderModelsResult> {
|
||||
const normalizedProvider = provider.toLowerCase()
|
||||
const models = MODELS_BY_PROVIDER[normalizedProvider]
|
||||
|
||||
if (!models) {
|
||||
const validProviders = Object.keys(MODELS_BY_PROVIDER).join(', ')
|
||||
const error: CommandError = {
|
||||
code: 'UNKNOWN_PROVIDER',
|
||||
message: `Unknown provider: ${provider}`,
|
||||
details: `Valid providers: ${validProviders}`,
|
||||
}
|
||||
throw error
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'list',
|
||||
data: models,
|
||||
schema: providerModelsSchema,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user