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
14 changes: 12 additions & 2 deletions src/cli/args.ts
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,16 @@ export function parseCliArgs(argv: string[] = process.argv.slice(2)): ParsedArgs

// Handle setup-app command
if (positionals.includes('setup-app')) {
const port = values.port ? parseInt(values.port as string, 10) : 3000;
if (Number.isNaN(port)) {
console.error(`Invalid --port value: ${values.port}`);
process.exit(1);
}
const timeout = values.timeout ? parseInt(values.timeout as string, 10) : 300;
if (Number.isNaN(timeout)) {
console.error(`Invalid --timeout value: ${values.timeout}`);
process.exit(1);
}
return {
command: 'setup-app',
options: CLIOptionsSchema.parse({
Expand All @@ -404,8 +414,8 @@ export function parseCliArgs(argv: string[] = process.argv.slice(2)): ParsedArgs
}),
setupAppOptions: {
org: values.org as string | undefined,
port: values.port ? parseInt(values.port as string, 10) : 3000,
timeout: values.timeout ? parseInt(values.timeout as string, 10) : 300,
port,
timeout,
name: values.name as string | undefined,
open: !values['no-open'],
},
Expand Down
71 changes: 39 additions & 32 deletions src/cli/commands/add.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,28 @@ async function promptRemoteSkillSelection(
}
}

/**
* Resolve which skill to add from explicit option, interactive prompt, or error.
* Returns the skill name, or null if the user cancelled, or a numeric exit code on error.
*/
async function resolveSkillName(
options: CLIOptions,
reporter: Reporter,
prompt: () => Promise<string | null>,
usageTip: string,
): Promise<string | number> {
if (options.skill) {
return options.skill;
}
if (reporter.mode.isTTY) {
const selected = await prompt();
return selected ?? 0;
}
reporter.error('Skill name required when not running interactively.');
reporter.tip(usageTip);
return 1;
}

const DEFAULT_TRIGGERS = [
{
type: 'pull_request' as const,
Expand Down Expand Up @@ -271,21 +293,15 @@ async function runAddRemote(
}

// Get skill to add (from --skill or interactive prompt)
let skillName: string | null;

if (options.skill) {
skillName = options.skill;
} else if (reporter.mode.isTTY) {
reporter.blank();
skillName = await promptRemoteSkillSelection(remoteSkills, configuredSkills, reporter);
if (!skillName) {
return 0; // User quit or no skills available
}
} else {
reporter.error('Skill name required when not running interactively.');
reporter.tip(`Use: warden add --remote ${remote} --skill <name>`);
return 1;
}
if (!options.skill && reporter.mode.isTTY) reporter.blank();
const resolved = await resolveSkillName(
options,
reporter,
() => promptRemoteSkillSelection(remoteSkills, configuredSkills, reporter),
`Use: warden add --remote ${remote} --skill <name>`,
);
if (typeof resolved === 'number') return resolved;
const skillName = resolved;

// Validate skill exists in remote, retry with fresh fetch if using stale cache
let availableSkills = remoteSkills;
Expand Down Expand Up @@ -413,23 +429,14 @@ export async function runAdd(options: CLIOptions, reporter: Reporter): Promise<n
}

// 8. Get skill to add (from arg or interactive prompt)
let skillName: string | null;

if (options.skill) {
// Non-interactive: skill specified as argument
skillName = options.skill;
} else if (reporter.mode.isTTY) {
// Interactive mode
skillName = await promptSkillSelection(skills, configuredSkills, reporter);
if (!skillName) {
return 0; // User quit or no skills available
}
} else {
// Non-TTY and no skill specified
reporter.error('Skill name required when not running interactively.');
reporter.tip('Use: warden add <skill-name> or warden add --list');
return 1;
}
const resolved = await resolveSkillName(
options,
reporter,
() => promptSkillSelection(skills, configuredSkills, reporter),
'Use: warden add <skill-name> or warden add --list',
);
if (typeof resolved === 'number') return resolved;
const skillName = resolved;

// 9. Validate skill exists
if (!skills.has(skillName)) {
Expand Down