refactor(cli): extract common command options into reusable helpers
This commit is contained in:
+102
-101
@@ -21,6 +21,12 @@ import { runWaitCommand } from './commands/agent/wait.js'
|
||||
import { runAttachCommand } from './commands/agent/attach.js'
|
||||
import { withOutput } from './output/index.js'
|
||||
import { onboardCommand } from './commands/onboard.js'
|
||||
import {
|
||||
addDaemonHostOption,
|
||||
addJsonAndDaemonHostOptions,
|
||||
addJsonOption,
|
||||
collectMultiple,
|
||||
} from './utils/command-options.js'
|
||||
|
||||
const require = createRequire(import.meta.url)
|
||||
|
||||
@@ -38,11 +44,6 @@ function resolveCliVersion(): string {
|
||||
|
||||
const VERSION = resolveCliVersion()
|
||||
|
||||
// Helper function to collect multiple option values into an array
|
||||
function collectMultiple(value: string, previous: string[]): string[] {
|
||||
return previous.concat([value])
|
||||
}
|
||||
|
||||
export function createCli(): Command {
|
||||
const program = new Command()
|
||||
|
||||
@@ -58,102 +59,100 @@ export function createCli(): Command {
|
||||
.option('--no-color', 'disable colored output')
|
||||
|
||||
// Primary agent commands (top-level)
|
||||
program
|
||||
.command('ls')
|
||||
.description('List agents. By default excludes archived agents.')
|
||||
.option('-a, --all', 'Include archived agents')
|
||||
.option('-g, --global', 'Legacy no-op (kept for compatibility)')
|
||||
.option('--label <key=value>', 'Filter by label (can be used multiple times)', collectMultiple, [])
|
||||
.option('--thinking <id>', 'Filter by thinking option ID')
|
||||
.option('--json', 'Output in JSON format')
|
||||
.option('--host <host>', 'Daemon host target (default: local socket/pipe, then localhost:6767)')
|
||||
.action(withOutput(runLsCommand))
|
||||
addJsonAndDaemonHostOptions(
|
||||
program
|
||||
.command('ls')
|
||||
.description('List agents. By default excludes archived agents.')
|
||||
.option('-a, --all', 'Include archived agents')
|
||||
.option('-g, --global', 'Legacy no-op (kept for compatibility)')
|
||||
.option('--label <key=value>', 'Filter by label (can be used multiple times)', collectMultiple, [])
|
||||
.option('--thinking <id>', 'Filter by thinking option ID')
|
||||
).action(withOutput(runLsCommand))
|
||||
|
||||
program
|
||||
.command('run')
|
||||
.description('Create and start an agent with a task')
|
||||
.argument('<prompt>', 'The task/prompt for the agent')
|
||||
.option('-d, --detach', 'Run in background (detached)')
|
||||
.option('--name <name>', 'Assign a name/title to the agent')
|
||||
.option('--provider <provider>', 'Agent provider: claude | codex | opencode', 'claude')
|
||||
.option('--model <model>', 'Model to use (e.g., claude-sonnet-4-20250514, claude-3-5-haiku-20241022)')
|
||||
.option('--thinking <id>', 'Thinking option ID to use for this run')
|
||||
.option('--mode <mode>', 'Provider-specific mode (e.g., plan, default, bypass)')
|
||||
.option('--worktree <name>', 'Create agent in a new git worktree')
|
||||
.option('--base <branch>', 'Base branch for worktree (default: current branch)')
|
||||
.option('--image <path>', 'Attach image(s) to the initial prompt (can be used multiple times)', collectMultiple, [])
|
||||
.option('--cwd <path>', 'Working directory (default: current)')
|
||||
.option('--label <key=value>', 'Add label(s) to the agent (can be used multiple times)', collectMultiple, [])
|
||||
.option('--output-schema <schema>', 'Output JSON matching the provided schema file path or inline JSON schema')
|
||||
.option('--json', 'Output in JSON format')
|
||||
.option('--host <host>', 'Daemon host target (default: local socket/pipe, then localhost:6767)')
|
||||
.action(withOutput(runRunCommand))
|
||||
addJsonAndDaemonHostOptions(
|
||||
program
|
||||
.command('run')
|
||||
.description('Create and start an agent with a task')
|
||||
.argument('<prompt>', 'The task/prompt for the agent')
|
||||
.option('-d, --detach', 'Run in background (detached)')
|
||||
.option('--name <name>', 'Assign a name/title to the agent')
|
||||
.option('--provider <provider>', 'Agent provider: claude | codex | opencode', 'claude')
|
||||
.option('--model <model>', 'Model to use (e.g., claude-sonnet-4-20250514, claude-3-5-haiku-20241022)')
|
||||
.option('--thinking <id>', 'Thinking option ID to use for this run')
|
||||
.option('--mode <mode>', 'Provider-specific mode (e.g., plan, default, bypass)')
|
||||
.option('--worktree <name>', 'Create agent in a new git worktree')
|
||||
.option('--base <branch>', 'Base branch for worktree (default: current branch)')
|
||||
.option(
|
||||
'--image <path>',
|
||||
'Attach image(s) to the initial prompt (can be used multiple times)',
|
||||
collectMultiple,
|
||||
[]
|
||||
)
|
||||
.option('--cwd <path>', 'Working directory (default: current)')
|
||||
.option('--label <key=value>', 'Add label(s) to the agent (can be used multiple times)', collectMultiple, [])
|
||||
.option('--output-schema <schema>', 'Output JSON matching the provided schema file path or inline JSON schema')
|
||||
).action(withOutput(runRunCommand))
|
||||
|
||||
program
|
||||
.command('attach')
|
||||
.description("Attach to a running agent's output stream")
|
||||
.argument('<id>', 'Agent ID (or prefix)')
|
||||
.option('--host <host>', 'Daemon host target (default: local socket/pipe, then localhost:6767)')
|
||||
.action(runAttachCommand)
|
||||
addDaemonHostOption(
|
||||
program
|
||||
.command('attach')
|
||||
.description("Attach to a running agent's output stream")
|
||||
.argument('<id>', 'Agent ID (or prefix)')
|
||||
).action(runAttachCommand)
|
||||
|
||||
program
|
||||
.command('logs')
|
||||
.description('View agent activity/timeline')
|
||||
.argument('<id>', 'Agent ID (or prefix)')
|
||||
.option('-f, --follow', 'Follow log output (streaming)')
|
||||
.option('--tail <n>', 'Show last n entries')
|
||||
.option('--filter <type>', 'Filter by event type (tools, text, errors, permissions)')
|
||||
.option('--since <time>', 'Show logs since timestamp')
|
||||
.option('--host <host>', 'Daemon host target (default: local socket/pipe, then localhost:6767)')
|
||||
.action(runLogsCommand)
|
||||
addDaemonHostOption(
|
||||
program
|
||||
.command('logs')
|
||||
.description('View agent activity/timeline')
|
||||
.argument('<id>', 'Agent ID (or prefix)')
|
||||
.option('-f, --follow', 'Follow log output (streaming)')
|
||||
.option('--tail <n>', 'Show last n entries')
|
||||
.option('--filter <type>', 'Filter by event type (tools, text, errors, permissions)')
|
||||
.option('--since <time>', 'Show logs since timestamp')
|
||||
).action(runLogsCommand)
|
||||
|
||||
program
|
||||
.command('stop')
|
||||
.description('Interrupt an agent if it is running (no-op for idle agents)')
|
||||
.argument('[id]', 'Agent ID (or prefix) - optional if --all or --cwd specified')
|
||||
.option('--all', 'Stop all agents')
|
||||
.option('--cwd <path>', 'Stop all agents in directory')
|
||||
.option('--json', 'Output in JSON format')
|
||||
.option('--host <host>', 'Daemon host target (default: local socket/pipe, then localhost:6767)')
|
||||
.action(withOutput(runStopCommand))
|
||||
addJsonAndDaemonHostOptions(
|
||||
program
|
||||
.command('stop')
|
||||
.description('Interrupt an agent if it is running (no-op for idle agents)')
|
||||
.argument('[id]', 'Agent ID (or prefix) - optional if --all or --cwd specified')
|
||||
.option('--all', 'Stop all agents')
|
||||
.option('--cwd <path>', 'Stop all agents in directory')
|
||||
).action(withOutput(runStopCommand))
|
||||
|
||||
program
|
||||
.command('delete')
|
||||
.description('Delete an agent (interrupt if running, then hard-delete)')
|
||||
.argument('[id]', 'Agent ID (or prefix) - optional if --all or --cwd specified')
|
||||
.option('--all', 'Delete all agents')
|
||||
.option('--cwd <path>', 'Delete all agents in directory')
|
||||
.option('--json', 'Output in JSON format')
|
||||
.option('--host <host>', 'Daemon host target (default: local socket/pipe, then localhost:6767)')
|
||||
.action(withOutput(runDeleteCommand))
|
||||
addJsonAndDaemonHostOptions(
|
||||
program
|
||||
.command('delete')
|
||||
.description('Delete an agent (interrupt if running, then hard-delete)')
|
||||
.argument('[id]', 'Agent ID (or prefix) - optional if --all or --cwd specified')
|
||||
.option('--all', 'Delete all agents')
|
||||
.option('--cwd <path>', 'Delete all agents in directory')
|
||||
).action(withOutput(runDeleteCommand))
|
||||
|
||||
program
|
||||
.command('send')
|
||||
.description('Send a message/task to an existing agent')
|
||||
.argument('<id>', 'Agent ID (or prefix)')
|
||||
.argument('<prompt>', 'The message to send')
|
||||
.option('--no-wait', 'Return immediately without waiting for completion')
|
||||
.option('--image <path>', 'Attach image(s) to the message', collectMultiple, [])
|
||||
.option('--json', 'Output in JSON format')
|
||||
.option('--host <host>', 'Daemon host target (default: local socket/pipe, then localhost:6767)')
|
||||
.action(withOutput(runSendCommand))
|
||||
addJsonAndDaemonHostOptions(
|
||||
program
|
||||
.command('send')
|
||||
.description('Send a message/task to an existing agent')
|
||||
.argument('<id>', 'Agent ID (or prefix)')
|
||||
.argument('<prompt>', 'The message to send')
|
||||
.option('--no-wait', 'Return immediately without waiting for completion')
|
||||
.option('--image <path>', 'Attach image(s) to the message', collectMultiple, [])
|
||||
).action(withOutput(runSendCommand))
|
||||
|
||||
program
|
||||
.command('inspect')
|
||||
.description('Show detailed information about an agent')
|
||||
.argument('<id>', 'Agent ID (or prefix)')
|
||||
.option('--json', 'Output in JSON format')
|
||||
.option('--host <host>', 'Daemon host target (default: local socket/pipe, then localhost:6767)')
|
||||
.action(withOutput(runInspectCommand))
|
||||
addJsonAndDaemonHostOptions(
|
||||
program
|
||||
.command('inspect')
|
||||
.description('Show detailed information about an agent')
|
||||
.argument('<id>', 'Agent ID (or prefix)')
|
||||
).action(withOutput(runInspectCommand))
|
||||
|
||||
program
|
||||
.command('wait')
|
||||
.description('Wait for an agent to become idle')
|
||||
.argument('<id>', 'Agent ID (or prefix)')
|
||||
.option('--timeout <seconds>', 'Maximum wait time (default: no limit)')
|
||||
.option('--json', 'Output in JSON format')
|
||||
.option('--host <host>', 'Daemon host target (default: local socket/pipe, then localhost:6767)')
|
||||
.action(withOutput(runWaitCommand))
|
||||
addJsonAndDaemonHostOptions(
|
||||
program
|
||||
.command('wait')
|
||||
.description('Wait for an agent to become idle')
|
||||
.argument('<id>', 'Agent ID (or prefix)')
|
||||
.option('--timeout <seconds>', 'Maximum wait time (default: no limit)')
|
||||
).action(withOutput(runWaitCommand))
|
||||
|
||||
// Top-level local daemon shortcuts
|
||||
program.addCommand(onboardCommand())
|
||||
@@ -168,17 +167,19 @@ export function createCli(): Command {
|
||||
await runDaemonUpdateCommandOrExit(options)
|
||||
})
|
||||
|
||||
program
|
||||
.command('status')
|
||||
.description('Show local daemon status (alias for "paseo daemon status")')
|
||||
.option('--json', 'Output in JSON format')
|
||||
addJsonOption(
|
||||
program
|
||||
.command('status')
|
||||
.description('Show local daemon status (alias for "paseo daemon status")')
|
||||
)
|
||||
.option('--home <path>', 'Paseo home directory (default: ~/.paseo)')
|
||||
.action(withOutput(runDaemonStatusCommand))
|
||||
|
||||
program
|
||||
.command('restart')
|
||||
.description('Restart local daemon (alias for "paseo daemon restart")')
|
||||
.option('--json', 'Output in JSON format')
|
||||
addJsonOption(
|
||||
program
|
||||
.command('restart')
|
||||
.description('Restart local daemon (alias for "paseo daemon restart")')
|
||||
)
|
||||
.option('--home <path>', 'Paseo home directory (default: ~/.paseo)')
|
||||
.option('--timeout <seconds>', 'Wait timeout before force step (default: 15)')
|
||||
.option('--force', 'Send SIGKILL if graceful stop times out')
|
||||
|
||||
@@ -12,142 +12,132 @@ import { runWaitCommand } from './wait.js'
|
||||
import { runAttachCommand } from './attach.js'
|
||||
import { runUpdateCommand } from './update.js'
|
||||
import { withOutput } from '../../output/index.js'
|
||||
import {
|
||||
addDaemonHostOption,
|
||||
addJsonAndDaemonHostOptions,
|
||||
collectMultiple,
|
||||
} from '../../utils/command-options.js'
|
||||
|
||||
export function createAgentCommand(): Command {
|
||||
const agent = new Command('agent').description('Manage agents (advanced operations)')
|
||||
|
||||
// Helper function to collect multiple option values into an array
|
||||
const collectMultiple = (value: string, previous: string[]): string[] => {
|
||||
return previous.concat([value])
|
||||
}
|
||||
|
||||
// Primary agent commands (same as top-level)
|
||||
agent
|
||||
.command('ls')
|
||||
.description('List agents. By default excludes archived agents.')
|
||||
.option('-a, --all', 'Include archived agents')
|
||||
.option('-g, --global', 'Legacy no-op (kept for compatibility)')
|
||||
.option('--label <key=value>', 'Filter by label (can be used multiple times)', collectMultiple, [])
|
||||
.option('--thinking <id>', 'Filter by thinking option ID')
|
||||
.option('--json', 'Output in JSON format')
|
||||
.option('--host <host>', 'Daemon host target (default: local socket/pipe, then localhost:6767)')
|
||||
.action(withOutput(runLsCommand))
|
||||
addJsonAndDaemonHostOptions(
|
||||
agent
|
||||
.command('ls')
|
||||
.description('List agents. By default excludes archived agents.')
|
||||
.option('-a, --all', 'Include archived agents')
|
||||
.option('-g, --global', 'Legacy no-op (kept for compatibility)')
|
||||
.option('--label <key=value>', 'Filter by label (can be used multiple times)', collectMultiple, [])
|
||||
.option('--thinking <id>', 'Filter by thinking option ID')
|
||||
).action(withOutput(runLsCommand))
|
||||
|
||||
agent
|
||||
.command('run')
|
||||
.description('Create and start an agent with a task')
|
||||
.argument('<prompt>', 'The task/prompt for the agent')
|
||||
.option('-d, --detach', 'Run in background (detached)')
|
||||
.option('--name <name>', 'Assign a name/title to the agent')
|
||||
.option('--provider <provider>', 'Agent provider: claude | codex | opencode', 'claude')
|
||||
.option('--model <model>', 'Model to use (e.g., claude-sonnet-4-20250514, claude-3-5-haiku-20241022)')
|
||||
.option('--thinking <id>', 'Thinking option ID to use for this run')
|
||||
.option('--mode <mode>', 'Provider-specific mode (e.g., plan, default, bypass)')
|
||||
.option('--cwd <path>', 'Working directory (default: current)')
|
||||
.option('--label <key=value>', 'Add label(s) to the agent (can be used multiple times)', collectMultiple, [])
|
||||
.option('--output-schema <schema>', 'Output JSON matching the provided schema file path or inline JSON schema')
|
||||
.option('--json', 'Output in JSON format')
|
||||
.option('--host <host>', 'Daemon host target (default: local socket/pipe, then localhost:6767)')
|
||||
.action(withOutput(runRunCommand))
|
||||
addJsonAndDaemonHostOptions(
|
||||
agent
|
||||
.command('run')
|
||||
.description('Create and start an agent with a task')
|
||||
.argument('<prompt>', 'The task/prompt for the agent')
|
||||
.option('-d, --detach', 'Run in background (detached)')
|
||||
.option('--name <name>', 'Assign a name/title to the agent')
|
||||
.option('--provider <provider>', 'Agent provider: claude | codex | opencode', 'claude')
|
||||
.option('--model <model>', 'Model to use (e.g., claude-sonnet-4-20250514, claude-3-5-haiku-20241022)')
|
||||
.option('--thinking <id>', 'Thinking option ID to use for this run')
|
||||
.option('--mode <mode>', 'Provider-specific mode (e.g., plan, default, bypass)')
|
||||
.option('--cwd <path>', 'Working directory (default: current)')
|
||||
.option('--label <key=value>', 'Add label(s) to the agent (can be used multiple times)', collectMultiple, [])
|
||||
.option('--output-schema <schema>', 'Output JSON matching the provided schema file path or inline JSON schema')
|
||||
).action(withOutput(runRunCommand))
|
||||
|
||||
agent
|
||||
.command('attach')
|
||||
.description("Attach to a running agent's output stream")
|
||||
.argument('<id>', 'Agent ID (or prefix)')
|
||||
.option('--host <host>', 'Daemon host target (default: local socket/pipe, then localhost:6767)')
|
||||
.action(runAttachCommand)
|
||||
addDaemonHostOption(
|
||||
agent
|
||||
.command('attach')
|
||||
.description("Attach to a running agent's output stream")
|
||||
.argument('<id>', 'Agent ID (or prefix)')
|
||||
).action(runAttachCommand)
|
||||
|
||||
agent
|
||||
.command('logs')
|
||||
.description('View agent activity/timeline')
|
||||
.argument('<id>', 'Agent ID (or prefix)')
|
||||
.option('-f, --follow', 'Follow log output (streaming)')
|
||||
.option('--tail <n>', 'Show last n entries')
|
||||
.option('--filter <type>', 'Filter by event type (tools, text, errors, permissions)')
|
||||
.option('--host <host>', 'Daemon host target (default: local socket/pipe, then localhost:6767)')
|
||||
.action(runLogsCommand)
|
||||
addDaemonHostOption(
|
||||
agent
|
||||
.command('logs')
|
||||
.description('View agent activity/timeline')
|
||||
.argument('<id>', 'Agent ID (or prefix)')
|
||||
.option('-f, --follow', 'Follow log output (streaming)')
|
||||
.option('--tail <n>', 'Show last n entries')
|
||||
.option('--filter <type>', 'Filter by event type (tools, text, errors, permissions)')
|
||||
).action(runLogsCommand)
|
||||
|
||||
agent
|
||||
.command('stop')
|
||||
.description('Interrupt an agent if it is running (no-op for idle agents)')
|
||||
.argument('[id]', 'Agent ID (or prefix) - optional if --all or --cwd specified')
|
||||
.option('--all', 'Stop all agents')
|
||||
.option('--cwd <path>', 'Stop all agents in directory')
|
||||
.option('--json', 'Output in JSON format')
|
||||
.option('--host <host>', 'Daemon host target (default: local socket/pipe, then localhost:6767)')
|
||||
.action(withOutput(runStopCommand))
|
||||
addJsonAndDaemonHostOptions(
|
||||
agent
|
||||
.command('stop')
|
||||
.description('Interrupt an agent if it is running (no-op for idle agents)')
|
||||
.argument('[id]', 'Agent ID (or prefix) - optional if --all or --cwd specified')
|
||||
.option('--all', 'Stop all agents')
|
||||
.option('--cwd <path>', 'Stop all agents in directory')
|
||||
).action(withOutput(runStopCommand))
|
||||
|
||||
agent
|
||||
.command('delete')
|
||||
.description('Delete an agent (interrupt if running, then hard-delete)')
|
||||
.argument('[id]', 'Agent ID (or prefix) - optional if --all or --cwd specified')
|
||||
.option('--all', 'Delete all agents')
|
||||
.option('--cwd <path>', 'Delete all agents in directory')
|
||||
.option('--json', 'Output in JSON format')
|
||||
.option('--host <host>', 'Daemon host target (default: local socket/pipe, then localhost:6767)')
|
||||
.action(withOutput(runDeleteCommand))
|
||||
addJsonAndDaemonHostOptions(
|
||||
agent
|
||||
.command('delete')
|
||||
.description('Delete an agent (interrupt if running, then hard-delete)')
|
||||
.argument('[id]', 'Agent ID (or prefix) - optional if --all or --cwd specified')
|
||||
.option('--all', 'Delete all agents')
|
||||
.option('--cwd <path>', 'Delete all agents in directory')
|
||||
).action(withOutput(runDeleteCommand))
|
||||
|
||||
agent
|
||||
.command('send')
|
||||
.description('Send a message/task to an existing agent')
|
||||
.argument('<id>', 'Agent ID (or prefix)')
|
||||
.argument('<prompt>', 'The message to send')
|
||||
.option('--no-wait', 'Return immediately without waiting for completion')
|
||||
.option('--json', 'Output in JSON format')
|
||||
.option('--host <host>', 'Daemon host target (default: local socket/pipe, then localhost:6767)')
|
||||
.action(withOutput(runSendCommand))
|
||||
addJsonAndDaemonHostOptions(
|
||||
agent
|
||||
.command('send')
|
||||
.description('Send a message/task to an existing agent')
|
||||
.argument('<id>', 'Agent ID (or prefix)')
|
||||
.argument('<prompt>', 'The message to send')
|
||||
.option('--no-wait', 'Return immediately without waiting for completion')
|
||||
).action(withOutput(runSendCommand))
|
||||
|
||||
agent
|
||||
.command('inspect')
|
||||
.description('Show detailed information about an agent')
|
||||
.argument('<id>', 'Agent ID (or prefix)')
|
||||
.option('--json', 'Output in JSON format')
|
||||
.option('--host <host>', 'Daemon host target (default: local socket/pipe, then localhost:6767)')
|
||||
.action(withOutput(runInspectCommand))
|
||||
addJsonAndDaemonHostOptions(
|
||||
agent
|
||||
.command('inspect')
|
||||
.description('Show detailed information about an agent')
|
||||
.argument('<id>', 'Agent ID (or prefix)')
|
||||
).action(withOutput(runInspectCommand))
|
||||
|
||||
agent
|
||||
.command('wait')
|
||||
.description('Wait for an agent to become idle')
|
||||
.argument('<id>', 'Agent ID (or prefix)')
|
||||
.option('--timeout <seconds>', 'Maximum wait time (default: no limit)')
|
||||
.option('--json', 'Output in JSON format')
|
||||
.option('--host <host>', 'Daemon host target (default: local socket/pipe, then localhost:6767)')
|
||||
.action(withOutput(runWaitCommand))
|
||||
addJsonAndDaemonHostOptions(
|
||||
agent
|
||||
.command('wait')
|
||||
.description('Wait for an agent to become idle')
|
||||
.argument('<id>', 'Agent ID (or prefix)')
|
||||
.option('--timeout <seconds>', 'Maximum wait time (default: no limit)')
|
||||
).action(withOutput(runWaitCommand))
|
||||
|
||||
// Advanced agent commands (less common operations)
|
||||
agent
|
||||
.command('mode')
|
||||
.description("Change an agent's operational mode")
|
||||
.argument('<id>', 'Agent ID (or prefix)')
|
||||
.argument('[mode]', 'Mode to set (required unless --list)')
|
||||
.option('--list', 'List available modes for this agent')
|
||||
.option('--json', 'Output in JSON format')
|
||||
.option('--host <host>', 'Daemon host target (default: local socket/pipe, then localhost:6767)')
|
||||
.action(withOutput(runModeCommand))
|
||||
addJsonAndDaemonHostOptions(
|
||||
agent
|
||||
.command('mode')
|
||||
.description("Change an agent's operational mode")
|
||||
.argument('<id>', 'Agent ID (or prefix)')
|
||||
.argument('[mode]', 'Mode to set (required unless --list)')
|
||||
.option('--list', 'List available modes for this agent')
|
||||
).action(withOutput(runModeCommand))
|
||||
|
||||
agent
|
||||
.command('archive')
|
||||
.description('Archive an agent (soft-delete)')
|
||||
.argument('<id>', 'Agent ID (or prefix)')
|
||||
.option('--force', 'Force archive running agent (interrupts active run first)')
|
||||
.option('--json', 'Output in JSON format')
|
||||
.option('--host <host>', 'Daemon host target (default: local socket/pipe, then localhost:6767)')
|
||||
.action(withOutput(runArchiveCommand))
|
||||
addJsonAndDaemonHostOptions(
|
||||
agent
|
||||
.command('archive')
|
||||
.description('Archive an agent (soft-delete)')
|
||||
.argument('<id>', 'Agent ID (or prefix)')
|
||||
.option('--force', 'Force archive running agent (interrupts active run first)')
|
||||
).action(withOutput(runArchiveCommand))
|
||||
|
||||
agent
|
||||
.command('update')
|
||||
.description("Update an agent's metadata")
|
||||
.argument('<id>', 'Agent ID (or prefix)')
|
||||
.option('--name <name>', "Update the agent's display name")
|
||||
.option(
|
||||
'--label <label>',
|
||||
'Add/set label(s) on the agent (can be used multiple times or comma-separated)',
|
||||
collectMultiple,
|
||||
[]
|
||||
)
|
||||
.option('--json', 'Output in JSON format')
|
||||
.option('--host <host>', 'Daemon host target (default: local socket/pipe, then localhost:6767)')
|
||||
.action(withOutput(runUpdateCommand))
|
||||
addJsonAndDaemonHostOptions(
|
||||
agent
|
||||
.command('update')
|
||||
.description("Update an agent's metadata")
|
||||
.argument('<id>', 'Agent ID (or prefix)')
|
||||
.option('--name <name>', "Update the agent's display name")
|
||||
.option(
|
||||
'--label <label>',
|
||||
'Add/set label(s) on the agent (can be used multiple times or comma-separated)',
|
||||
collectMultiple,
|
||||
[]
|
||||
)
|
||||
).action(withOutput(runUpdateCommand))
|
||||
|
||||
return agent
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import { runRestartCommand } from './restart.js'
|
||||
import { pairCommand } from './pair.js'
|
||||
import { updateCommand } from './update.js'
|
||||
import { withOutput } from '../../output/index.js'
|
||||
import { addJsonOption } from '../../utils/command-options.js'
|
||||
|
||||
export function createDaemonCommand(): Command {
|
||||
const daemon = new Command('daemon').description('Manage the Paseo daemon')
|
||||
@@ -14,26 +15,29 @@ export function createDaemonCommand(): Command {
|
||||
daemon.addCommand(pairCommand())
|
||||
daemon.addCommand(updateCommand())
|
||||
|
||||
daemon
|
||||
.command('status')
|
||||
.description('Show local daemon status')
|
||||
.option('--json', 'Output in JSON format')
|
||||
addJsonOption(
|
||||
daemon
|
||||
.command('status')
|
||||
.description('Show local daemon status')
|
||||
)
|
||||
.option('--home <path>', 'Paseo home directory (default: ~/.paseo)')
|
||||
.action(withOutput(runStatusCommand))
|
||||
|
||||
daemon
|
||||
.command('stop')
|
||||
.description('Stop the local daemon')
|
||||
.option('--json', 'Output in JSON format')
|
||||
addJsonOption(
|
||||
daemon
|
||||
.command('stop')
|
||||
.description('Stop the local daemon')
|
||||
)
|
||||
.option('--home <path>', 'Paseo home directory (default: ~/.paseo)')
|
||||
.option('--timeout <seconds>', 'Wait timeout before failing (default: 15)')
|
||||
.option('--force', 'Send SIGKILL if graceful stop times out')
|
||||
.action(withOutput(runStopCommand))
|
||||
|
||||
daemon
|
||||
.command('restart')
|
||||
.description('Restart the local daemon')
|
||||
.option('--json', 'Output in JSON format')
|
||||
addJsonOption(
|
||||
daemon
|
||||
.command('restart')
|
||||
.description('Restart the local daemon')
|
||||
)
|
||||
.option('--home <path>', 'Paseo home directory (default: ~/.paseo)')
|
||||
.option('--timeout <seconds>', 'Wait timeout before force step (default: 15)')
|
||||
.option('--force', 'Send SIGKILL if graceful stop times out')
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Command } from 'commander'
|
||||
import chalk from 'chalk'
|
||||
import { generateLocalPairingOffer, loadConfig, resolvePaseoHome } from '@getpaseo/server'
|
||||
import { addJsonOption } from '../../utils/command-options.js'
|
||||
|
||||
interface PairOptions {
|
||||
home?: string
|
||||
@@ -8,9 +9,10 @@ interface PairOptions {
|
||||
}
|
||||
|
||||
export function pairCommand(): Command {
|
||||
return new Command('pair')
|
||||
.description('Print the daemon pairing QR code and link')
|
||||
.option('--json', 'Output in JSON format')
|
||||
return addJsonOption(
|
||||
new Command('pair')
|
||||
.description('Print the daemon pairing QR code and link')
|
||||
)
|
||||
.option('--home <path>', 'Paseo home directory (default: ~/.paseo)')
|
||||
.action(async (_options: PairOptions, command: Command) => {
|
||||
await runPairCommand(command.optsWithGlobals() as PairOptions)
|
||||
|
||||
@@ -3,39 +3,37 @@ import { runLsCommand } from './ls.js'
|
||||
import { runAllowCommand } from './allow.js'
|
||||
import { runDenyCommand } from './deny.js'
|
||||
import { withOutput } from '../../output/index.js'
|
||||
import { addJsonAndDaemonHostOptions } from '../../utils/command-options.js'
|
||||
|
||||
export function createPermitCommand(): Command {
|
||||
const permit = new Command('permit').description('Manage permission requests')
|
||||
|
||||
permit
|
||||
.command('ls')
|
||||
.description('List all pending permissions')
|
||||
.option('--json', 'Output in JSON format')
|
||||
.option('--host <host>', 'Daemon host target (default: local socket/pipe, then localhost:6767)')
|
||||
.action(withOutput(runLsCommand))
|
||||
addJsonAndDaemonHostOptions(
|
||||
permit
|
||||
.command('ls')
|
||||
.description('List all pending permissions')
|
||||
).action(withOutput(runLsCommand))
|
||||
|
||||
permit
|
||||
.command('allow')
|
||||
.description('Allow a permission request')
|
||||
.argument('<agent>', 'Agent ID (or prefix)')
|
||||
.argument('[req_id]', 'Permission request ID (optional if --all)')
|
||||
.option('--all', 'Allow all pending permissions for this agent')
|
||||
.option('--input <json>', 'Modified input parameters (JSON)')
|
||||
.option('--json', 'Output in JSON format')
|
||||
.option('--host <host>', 'Daemon host target (default: local socket/pipe, then localhost:6767)')
|
||||
.action(withOutput(runAllowCommand))
|
||||
addJsonAndDaemonHostOptions(
|
||||
permit
|
||||
.command('allow')
|
||||
.description('Allow a permission request')
|
||||
.argument('<agent>', 'Agent ID (or prefix)')
|
||||
.argument('[req_id]', 'Permission request ID (optional if --all)')
|
||||
.option('--all', 'Allow all pending permissions for this agent')
|
||||
.option('--input <json>', 'Modified input parameters (JSON)')
|
||||
).action(withOutput(runAllowCommand))
|
||||
|
||||
permit
|
||||
.command('deny')
|
||||
.description('Deny a permission request')
|
||||
.argument('<agent>', 'Agent ID (or prefix)')
|
||||
.argument('[req_id]', 'Permission request ID (optional if --all)')
|
||||
.option('--all', 'Deny all pending permissions for this agent')
|
||||
.option('--message <msg>', 'Denial reason message')
|
||||
.option('--interrupt', 'Stop agent after denial')
|
||||
.option('--json', 'Output in JSON format')
|
||||
.option('--host <host>', 'Daemon host target (default: local socket/pipe, then localhost:6767)')
|
||||
.action(withOutput(runDenyCommand))
|
||||
addJsonAndDaemonHostOptions(
|
||||
permit
|
||||
.command('deny')
|
||||
.description('Deny a permission request')
|
||||
.argument('<agent>', 'Agent ID (or prefix)')
|
||||
.argument('[req_id]', 'Permission request ID (optional if --all)')
|
||||
.option('--all', 'Deny all pending permissions for this agent')
|
||||
.option('--message <msg>', 'Denial reason message')
|
||||
.option('--interrupt', 'Stop agent after denial')
|
||||
).action(withOutput(runDenyCommand))
|
||||
|
||||
return permit
|
||||
}
|
||||
|
||||
@@ -2,25 +2,24 @@ import { Command } from 'commander'
|
||||
import { runLsCommand } from './ls.js'
|
||||
import { runModelsCommand } from './models.js'
|
||||
import { withOutput } from '../../output/index.js'
|
||||
import { addJsonAndDaemonHostOptions } from '../../utils/command-options.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 target (default: local socket/pipe, then localhost:6767)')
|
||||
.action(withOutput(runLsCommand))
|
||||
addJsonAndDaemonHostOptions(
|
||||
provider
|
||||
.command('ls')
|
||||
.description('List available providers and status')
|
||||
).action(withOutput(runLsCommand))
|
||||
|
||||
provider
|
||||
.command('models')
|
||||
.description('List models for a provider')
|
||||
.argument('<provider>', 'Provider name (claude, codex, opencode)')
|
||||
.option('--thinking', 'Include thinking option IDs for each model')
|
||||
.option('--json', 'Output in JSON format')
|
||||
.option('--host <host>', 'Daemon host target (default: local socket/pipe, then localhost:6767)')
|
||||
.action(withOutput(runModelsCommand))
|
||||
addJsonAndDaemonHostOptions(
|
||||
provider
|
||||
.command('models')
|
||||
.description('List models for a provider')
|
||||
.argument('<provider>', 'Provider name (claude, codex, opencode)')
|
||||
.option('--thinking', 'Include thinking option IDs for each model')
|
||||
).action(withOutput(runModelsCommand))
|
||||
|
||||
return provider
|
||||
}
|
||||
|
||||
@@ -1,29 +1,24 @@
|
||||
import { Command } from "commander";
|
||||
import { withOutput } from "../../output/index.js";
|
||||
import { runSpeechModelsCommand } from "./models.js";
|
||||
import { runSpeechDownloadCommand } from "./download.js";
|
||||
|
||||
function collectMultiple(value: string, previous: string[]): string[] {
|
||||
return previous.concat([value]);
|
||||
}
|
||||
import { Command } from 'commander'
|
||||
import { withOutput } from '../../output/index.js'
|
||||
import { runSpeechModelsCommand } from './models.js'
|
||||
import { runSpeechDownloadCommand } from './download.js'
|
||||
import { addJsonAndDaemonHostOptions, collectMultiple } from '../../utils/command-options.js'
|
||||
|
||||
export function createSpeechCommand(): Command {
|
||||
const speech = new Command("speech").description("Manage local speech models");
|
||||
const speech = new Command('speech').description('Manage local speech models')
|
||||
|
||||
speech
|
||||
.command("models")
|
||||
.description("List local speech model download status")
|
||||
.option("--json", "Output in JSON format")
|
||||
.option("--host <host>", "Daemon host target (default: local socket/pipe, then localhost:6767)")
|
||||
.action(withOutput(runSpeechModelsCommand));
|
||||
addJsonAndDaemonHostOptions(
|
||||
speech
|
||||
.command('models')
|
||||
.description('List local speech model download status')
|
||||
).action(withOutput(runSpeechModelsCommand))
|
||||
|
||||
speech
|
||||
.command("download")
|
||||
.description("Download local speech models")
|
||||
.option("--model <id>", "Model ID to download (repeatable)", collectMultiple, [])
|
||||
.option("--json", "Output in JSON format")
|
||||
.option("--host <host>", "Daemon host target (default: local socket/pipe, then localhost:6767)")
|
||||
.action(withOutput(runSpeechDownloadCommand));
|
||||
addJsonAndDaemonHostOptions(
|
||||
speech
|
||||
.command('download')
|
||||
.description('Download local speech models')
|
||||
.option('--model <id>', 'Model ID to download (repeatable)', collectMultiple, [])
|
||||
).action(withOutput(runSpeechDownloadCommand))
|
||||
|
||||
return speech;
|
||||
return speech
|
||||
}
|
||||
|
||||
@@ -2,24 +2,23 @@ import { Command } from 'commander'
|
||||
import { runLsCommand } from './ls.js'
|
||||
import { runArchiveCommand } from './archive.js'
|
||||
import { withOutput } from '../../output/index.js'
|
||||
import { addJsonAndDaemonHostOptions } from '../../utils/command-options.js'
|
||||
|
||||
export function createWorktreeCommand(): Command {
|
||||
const worktree = new Command('worktree').description('Manage Paseo-managed git worktrees')
|
||||
|
||||
worktree
|
||||
.command('ls')
|
||||
.description('List Paseo-managed git worktrees')
|
||||
.option('--json', 'Output in JSON format')
|
||||
.option('--host <host>', 'Daemon host target (default: local socket/pipe, then localhost:6767)')
|
||||
.action(withOutput(runLsCommand))
|
||||
addJsonAndDaemonHostOptions(
|
||||
worktree
|
||||
.command('ls')
|
||||
.description('List Paseo-managed git worktrees')
|
||||
).action(withOutput(runLsCommand))
|
||||
|
||||
worktree
|
||||
.command('archive')
|
||||
.description('Archive a worktree (removes worktree and associated branch)')
|
||||
.argument('<name>', 'Worktree name or branch name')
|
||||
.option('--json', 'Output in JSON format')
|
||||
.option('--host <host>', 'Daemon host target (default: local socket/pipe, then localhost:6767)')
|
||||
.action(withOutput(runArchiveCommand))
|
||||
addJsonAndDaemonHostOptions(
|
||||
worktree
|
||||
.command('archive')
|
||||
.description('Archive a worktree (removes worktree and associated branch)')
|
||||
.argument('<name>', 'Worktree name or branch name')
|
||||
).action(withOutput(runArchiveCommand))
|
||||
|
||||
return worktree
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import type { Command } from 'commander'
|
||||
|
||||
const JSON_OPTION_DESCRIPTION = 'Output in JSON format'
|
||||
const DAEMON_HOST_OPTION_DESCRIPTION =
|
||||
'Daemon host target (default: local socket/pipe, then localhost:6767)'
|
||||
|
||||
export function collectMultiple(value: string, previous: string[]): string[] {
|
||||
return previous.concat([value])
|
||||
}
|
||||
|
||||
export function addJsonOption<T extends Command>(command: T): T {
|
||||
command.option('--json', JSON_OPTION_DESCRIPTION)
|
||||
return command
|
||||
}
|
||||
|
||||
export function addDaemonHostOption<T extends Command>(command: T): T {
|
||||
command.option('--host <host>', DAEMON_HOST_OPTION_DESCRIPTION)
|
||||
return command
|
||||
}
|
||||
|
||||
export function addJsonAndDaemonHostOptions<T extends Command>(command: T): T {
|
||||
return addDaemonHostOption(addJsonOption(command))
|
||||
}
|
||||
Reference in New Issue
Block a user