Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@elevenlabs/cli",
"version": "0.4.3",
"version": "0.5.0",
"description": "CLI tool to manage ElevenLabs agents",
"type": "module",
"keywords": [
Expand Down
9 changes: 5 additions & 4 deletions src/agents/commands/add.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,11 @@ export function createAddCommand(): Command {
.option('--output-path <path>', 'Custom output path for the config file (optional)')
.option('--template <template>', 'Template type to use (default, minimal, voice-only, text-only, customer-service, assistant)')
.option('--from-file <path>', 'Create agent from an existing config file')
.option('--no-ui', 'Disable interactive UI')
.action(async (name: string | undefined, options: AddOptions & { ui: boolean }) => {
.option('--no-ui', 'Disable interactive UI (default, kept for backwards compatibility)')
.option('--human-friendly', 'Enable interactive terminal UI')
.action(async (name: string | undefined, options: AddOptions & { ui: boolean; humanFriendly?: boolean }) => {
try {
if (options.ui !== false && !options.outputPath && !options.fromFile) {
if (options.humanFriendly && !options.outputPath && !options.fromFile) {
// Use Ink UI for agent creation
const { waitUntilExit } = render(
React.createElement(AddAgentView, {
Expand All @@ -58,7 +59,7 @@ export function createAddCommand(): Command {

// Non-UI path requires name to be provided (or --from-file with name in the file)
if (!name && !options.fromFile) {
console.error('Error: Agent name is required when using --no-ui or --output-path');
console.error('Error: Agent name is required in non-interactive mode');
process.exit(1);
}

Expand Down
7 changes: 4 additions & 3 deletions src/agents/commands/branches.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ export function createBranchesCommand(): Command {
.description('List branches for an agent')
.requiredOption('--agent <agent_id>', 'Agent ID to list branches for')
.option('--include-archived', 'Include archived branches', false)
.option('--no-ui', 'Disable interactive UI')
.action(async (options: BranchesListOptions & { ui: boolean }) => {
.option('--no-ui', 'Disable interactive UI (default, kept for backwards compatibility)')
.option('--human-friendly', 'Enable interactive terminal UI')
.action(async (options: BranchesListOptions & { ui: boolean; humanFriendly?: boolean }) => {
try {
if (options.ui !== false) {
if (options.humanFriendly) {
const { waitUntilExit } = render(
React.createElement(BranchesListView, {
agent: options.agent,
Expand Down
7 changes: 4 additions & 3 deletions src/agents/commands/delete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ export function createDeleteCommand(): Command {
.description('Delete an agent locally and from ElevenLabs')
.argument('[agent_id]', 'ID of the agent to delete (omit with --all to delete all agents)')
.option('--all', 'Delete all agents', false)
.option('--no-ui', 'Disable interactive UI')
.action(async (agentId: string | undefined, options: { all: boolean; ui: boolean }) => {
.option('--no-ui', 'Disable interactive UI (default, kept for backwards compatibility)')
.option('--human-friendly', 'Enable interactive terminal UI')
.action(async (agentId: string | undefined, options: { all: boolean; ui: boolean; humanFriendly?: boolean }) => {
try {
if (options.all && agentId) {
console.error('Error: Cannot specify both agent_id and --all flag');
Expand All @@ -22,7 +23,7 @@ export function createDeleteCommand(): Command {
}

if (options.all) {
await deleteAllAgents(options.ui);
await deleteAllAgents(options.humanFriendly === true);
} else {
await deleteAgent(agentId!);
}
Expand Down
43 changes: 39 additions & 4 deletions src/agents/commands/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,36 @@ import { createTestCommand } from './test.js';
import { createBranchesCommand } from './branches.js';
import AgentsHelpView from '../ui/AgentsHelpView.js';

function printAgentsHelp() {
console.log('elevenlabs agents - Agent management commands\n');
console.log('Usage:');
console.log(' elevenlabs agents <command> [options]\n');
console.log('Commands:');
const commands = [
{ name: 'init [path]', description: 'Initialize project', options: ['--override Recreate existing project'] },
{ name: 'add [name]', description: 'Create a new agent and push to remote', options: ['--output-path <path> Custom output path for config file', '--from-file <path> Create agent from existing config file', '--template <template> Template type to use (default, minimal, voice-only, text-only, customer-service, assistant)'] },
{ name: 'list', description: 'List all local agents' },
{ name: 'delete [agent_id]', description: 'Delete agent', options: ['--all Delete all agents'] },
{ name: 'status', description: 'Show the status of agents' },
{ name: 'push', description: 'Push agents to ElevenLabs', options: ['--branch <branch> Push to a specific branch'] },
{ name: 'pull', description: 'Pull agents from ElevenLabs', options: ['--branch <branch> Pull from a specific branch', '--all-branches Pull all branches for each agent', '--update Update existing agents', '--all Pull all agents'] },
{ name: 'branches list', description: 'List branches for an agent', options: ['--agent <agent_id> Agent ID (required)', '--include-archived Include archived branches'] },
{ name: 'test <agent>', description: 'Run tests for an agent' },
{ name: 'templates [action]', description: 'Manage agent templates', options: ['list List available templates', 'show <name> Show template details'] },
{ name: 'widget <name>', description: 'Generate HTML widget snippet' },
];
for (const cmd of commands) {
console.log(` ${cmd.name.padEnd(28)}${cmd.description}`);
if (cmd.options) {
for (const opt of cmd.options) {
const [flag, ...descParts] = opt.split(' ');
console.log(` ${flag.padEnd(26)}${descParts.join(' ')}`);
}
}
}
console.log('\nEnable interactive UI with --human-friendly flag for any command');
}

export function createAgentsCommand(): Command {
const agents = new Command('agents');
agents.description('Manage ElevenLabs agents');
Expand All @@ -24,13 +54,18 @@ export function createAgentsCommand(): Command {

// Add custom help option
agents.option('-h, --help', 'Display help information');
agents.option('--human-friendly', 'Enable interactive terminal UI');

// Custom action when agents command is run without subcommands
agents.action(async () => {
const { waitUntilExit } = render(
React.createElement(AgentsHelpView)
);
await waitUntilExit();
if (process.argv.includes('--human-friendly')) {
const { waitUntilExit } = render(
React.createElement(AgentsHelpView)
);
await waitUntilExit();
} else {
printAgentsHelp();
}
process.exit(0);
});

Expand Down
7 changes: 4 additions & 3 deletions src/agents/commands/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,12 @@ export function createInitCommand(): Command {
return new Command('init')
.description('Initialize a new agent management project')
.argument('[path]', 'Path to initialize the project in', '.')
.option('--no-ui', 'Disable interactive UI')
.option('--no-ui', 'Disable interactive UI (default, kept for backwards compatibility)')
.option('--human-friendly', 'Enable interactive terminal UI')
.option('--override', 'Override existing files and recreate from scratch', false)
.action(async (projectPath: string, options: { ui: boolean; override: boolean }) => {
.action(async (projectPath: string, options: { ui: boolean; override: boolean; humanFriendly?: boolean }) => {
try {
if (options.ui !== false) {
if (options.humanFriendly) {
// Use Ink UI for initialization
const { waitUntilExit } = render(
React.createElement(InitView, { projectPath, override: options.override })
Expand Down
7 changes: 4 additions & 3 deletions src/agents/commands/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ import ListAgentsView from '../ui/ListAgentsView.js';
export function createListCommand(): Command {
return new Command('list')
.description('List all configured agents')
.option('--no-ui', 'Disable interactive UI')
.action(async (options: { ui: boolean }) => {
.option('--no-ui', 'Disable interactive UI (default, kept for backwards compatibility)')
.option('--human-friendly', 'Enable interactive terminal UI')
.action(async (options: { ui: boolean; humanFriendly?: boolean }) => {
try {
if (options.ui !== false) {
if (options.humanFriendly) {
// Use Ink UI for list-agents
const { waitUntilExit } = render(
React.createElement(ListAgentsView)
Expand Down
7 changes: 4 additions & 3 deletions src/agents/commands/pull.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ export function createPullCommand(): Command {
.option('--dry-run', 'Show what would be done without making changes', false)
.option('--update', 'Update existing items only, skip new')
.option('--all', 'Pull all (new + existing)')
.option('--no-ui', 'Disable interactive UI')
.action(async (options: PullOptions & { ui: boolean }) => {
.option('--no-ui', 'Disable interactive UI (default, kept for backwards compatibility)')
.option('--human-friendly', 'Enable interactive terminal UI')
.action(async (options: PullOptions & { ui: boolean; humanFriendly?: boolean }) => {
try {
if (options.branch && !options.agent) {
throw new Error('--branch requires --agent to be specified, since branch names are per-agent.');
Expand All @@ -35,7 +36,7 @@ export function createPullCommand(): Command {
await pullAgents(options);
return;
}
if (options.ui !== false) {
if (options.humanFriendly) {
// Use Ink UI for pull
const { waitUntilExit } = render(
React.createElement(PullView, {
Expand Down
7 changes: 4 additions & 3 deletions src/agents/commands/push.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,14 @@ export function createPushCommand(): Command {
.option('--branch <branch>', 'Specific branch name or ID to push to')
.option('--dry-run', 'Show what would be done without making changes', false)
.option('--version-description <text>', 'Description for the new version (only applies to updates)')
.option('--no-ui', 'Disable interactive UI')
.action(async (options: PushOptions & { ui: boolean }) => {
.option('--no-ui', 'Disable interactive UI (default, kept for backwards compatibility)')
.option('--human-friendly', 'Enable interactive terminal UI')
.action(async (options: PushOptions & { ui: boolean; humanFriendly?: boolean }) => {
try {
if (options.branch && !options.agent) {
throw new Error('--branch requires --agent to be specified, since branch names are per-agent.');
}
if (options.ui !== false) {
if (options.humanFriendly) {
// Use new Ink UI for push
const agentsConfigPath = path.resolve(AGENTS_CONFIG_FILE);
if (!(await fs.pathExists(agentsConfigPath))) {
Expand Down
7 changes: 4 additions & 3 deletions src/agents/commands/status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ interface StatusOptions {
export function createStatusCommand(): Command {
return new Command('status')
.description('Show the status of agents')
.option('--no-ui', 'Disable interactive UI')
.action(async (options: StatusOptions & { ui: boolean }) => {
.option('--no-ui', 'Disable interactive UI (default, kept for backwards compatibility)')
.option('--human-friendly', 'Enable interactive terminal UI')
.action(async (options: StatusOptions & { ui: boolean; humanFriendly?: boolean }) => {
try {
if (options.ui !== false) {
if (options.humanFriendly) {
// Use Ink UI for status display
const { waitUntilExit } = render(
React.createElement(StatusView, {})
Expand Down
5 changes: 3 additions & 2 deletions src/agents/commands/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ export function createTestCommand(): Command {
return new Command('test')
.description('Run tests for an agent')
.argument('<agent>', 'Name or ID of the agent to test')
.option('--no-ui', 'Disable interactive UI')
.action(async (agentId: string, options: { ui: boolean }) => {
.option('--no-ui', 'Disable interactive UI (default, kept for backwards compatibility)')
.option('--human-friendly', 'Enable interactive terminal UI')
.action(async (agentId: string, options: { ui: boolean; humanFriendly?: boolean }) => {
try {
if (options.ui !== false) {
// Use Ink UI for testing
Expand Down
2 changes: 1 addition & 1 deletion src/agents/ui/AgentsHelpView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ export const AgentsHelpView: React.FC = () => {

<Box marginTop={1}>
<Text color={theme.colors.text.muted}>
Disable UI mode with --no-ui flag for any command
Enable interactive UI with --human-friendly flag for any command
</Text>
</Box>
</App>
Expand Down
30 changes: 26 additions & 4 deletions src/auth/commands/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,23 @@ import { createWhoamiCommand } from './whoami.js';
import { createResidencyCommand } from './residency.js';
import AuthHelpView from '../ui/AuthHelpView.js';

function printAuthHelp() {
console.log('elevenlabs auth - Authentication commands\n');
console.log('Usage:');
console.log(' elevenlabs auth <command> [options]\n');
console.log('Commands:');
const commands = [
{ name: 'login', description: 'Login with your ElevenLabs API key' },
{ name: 'logout', description: 'Logout and remove stored API key' },
{ name: 'whoami', description: 'Show current login status' },
{ name: 'residency [location]', description: 'Set the API residency location' },
];
for (const cmd of commands) {
console.log(` ${cmd.name.padEnd(28)}${cmd.description}`);
}
console.log('\nEnable interactive UI with --human-friendly flag for any command');
}

export function createAuthCommand(): Command {
const auth = new Command('auth');
auth.description('Authentication and configuration commands');
Expand All @@ -17,13 +34,18 @@ export function createAuthCommand(): Command {

// Add custom help option
auth.option('-h, --help', 'Display help information');
auth.option('--human-friendly', 'Enable interactive terminal UI');

// Custom action when auth command is run without subcommands
auth.action(async () => {
const { waitUntilExit } = render(
React.createElement(AuthHelpView)
);
await waitUntilExit();
if (process.argv.includes('--human-friendly')) {
const { waitUntilExit } = render(
React.createElement(AuthHelpView)
);
await waitUntilExit();
} else {
printAuthHelp();
}
process.exit(0);
});

Expand Down
7 changes: 4 additions & 3 deletions src/auth/commands/login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ import { ElevenLabsClient } from '@elevenlabs/elevenlabs-js';
export function createLoginCommand(): Command {
return new Command('login')
.description('Login with your ElevenLabs API key')
.option('--no-ui', 'Disable interactive UI')
.action(async (options: { ui: boolean }) => {
.option('--no-ui', 'Disable interactive UI (default, kept for backwards compatibility)')
.option('--human-friendly', 'Enable interactive terminal UI')
.action(async (options: { ui: boolean; humanFriendly?: boolean }) => {
try {
if (options.ui !== false) {
if (options.humanFriendly) {
// Use Ink UI for login
const { waitUntilExit } = render(
React.createElement(LoginView, {})
Expand Down
7 changes: 4 additions & 3 deletions src/auth/commands/logout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import { removeApiKey, isLoggedIn } from '../../shared/config.js';
export function createLogoutCommand(): Command {
return new Command('logout')
.description('Logout and remove stored API key')
.option('--no-ui', 'Disable interactive UI')
.action(async (options: { ui: boolean }) => {
.option('--no-ui', 'Disable interactive UI (default, kept for backwards compatibility)')
.option('--human-friendly', 'Enable interactive terminal UI')
.action(async (options: { ui: boolean; humanFriendly?: boolean }) => {
try {
if (options.ui !== false) {
if (options.humanFriendly) {
// Use Ink UI for logout
const { waitUntilExit } = render(
React.createElement(LogoutView, {})
Expand Down
9 changes: 5 additions & 4 deletions src/auth/commands/residency.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ export function createResidencyCommand(): Command {
return new Command('residency')
.description('Set the API residency location')
.argument('[residency]', `Residency location (${LOCATIONS.join(', ')})`)
.option('--no-ui', 'Disable interactive UI')
.action(async (residency: string | undefined, options: { ui: boolean }) => {
.option('--no-ui', 'Disable interactive UI (default, kept for backwards compatibility)')
.option('--human-friendly', 'Enable interactive terminal UI')
.action(async (residency: string | undefined, options: { ui: boolean; humanFriendly?: boolean }) => {
try {
if (options.ui !== false && !residency) {
if (options.humanFriendly && !residency) {
// Use Ink UI for interactive residency selection
const { waitUntilExit } = render(
React.createElement(ResidencyView)
Expand All @@ -29,7 +30,7 @@ export function createResidencyCommand(): Command {
process.exit(1);
}

if (options.ui !== false) {
if (options.humanFriendly) {
// Use UI even with direct argument
const { waitUntilExit } = render(
React.createElement(ResidencyView, { initialResidency: residency })
Expand Down
7 changes: 4 additions & 3 deletions src/auth/commands/whoami.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import { getApiKey, getResidency } from '../../shared/config.js';
export function createWhoamiCommand(): Command {
return new Command('whoami')
.description('Show current login status')
.option('--no-ui', 'Disable interactive UI')
.action(async (options: { ui: boolean }) => {
.option('--no-ui', 'Disable interactive UI (default, kept for backwards compatibility)')
.option('--human-friendly', 'Enable interactive terminal UI')
.action(async (options: { ui: boolean; humanFriendly?: boolean }) => {
try {
if (options.ui !== false) {
if (options.humanFriendly) {
// Use Ink UI for whoami
const { waitUntilExit } = render(
React.createElement(WhoamiView)
Expand Down
2 changes: 1 addition & 1 deletion src/auth/ui/AuthHelpView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ export const AuthHelpView: React.FC = () => {

<Box marginTop={1}>
<Text color={theme.colors.text.muted}>
Disable UI mode with --no-ui flag for any command
Enable interactive UI with --human-friendly flag for any command
</Text>
</Box>
</App>
Expand Down
Loading
Loading