Skip to content
Merged
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
86 changes: 48 additions & 38 deletions src/utils/flags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,82 +3,92 @@
*
* Provides functions to parse flags and return remaining content.
*/
export interface ParsedFlags {
/**
* Map of flag names to boolean indicating presence.
*/
flags: Record<string, boolean>;
/**
* Remaining input string after removing flags.
*/
export interface ParsedFlags<T extends string = string> {
/** Map of flag names to boolean indicating presence. */
flags: Record<T, boolean>;
/** Remaining input string after removing flags. */
rest: string;
}

/**
* Parses the input string for boolean flags and returns the remaining content.
* @param {string} input - The input string containing flags and content.
* @param {string[]} flagNames - Array of flag names (without leading dashes) to parse.
* @returns {ParsedFlags} An object with flags map and remaining content string.
*
* @param input - The input string containing flags and content.
* @param flagNames - Array of flag names (without leading dashes) to parse.
* @returns An object with a flags map and the remaining content string.
*/
export function parseFlags(input: string, flagNames: string[]): ParsedFlags {
export function parseFlags<T extends string>(
input: string,
flagNames: readonly T[],
): ParsedFlags<T> {
const tokens = input.split(/\s+/).filter(Boolean);
const flags: Record<string, boolean> = {};
flagNames.forEach((name) => {
flags[name] = false;
});
const flagSet = new Set(flagNames);
const flags = Object.fromEntries(
flagNames.map((name) => [name, false]),
) as Record<T, boolean>;
const restTokens: string[] = [];

for (const token of tokens) {
if (token.startsWith('--')) {
const name = token.slice(2);
if (flagNames.includes(name)) {
const name = token.slice(2) as T;
if (flagSet.has(name)) {
flags[name] = true;
continue;
}
}
restTokens.push(token);
}

return { flags, rest: restTokens.join(' ') };
}

/**
* Options for prompt flag parsing.
*/
/** Options for prompt flag parsing. */
export interface PromptFlagOptions {
/** Include full conversation history */
includeFullHistory: boolean;
/** Create issues based on the output */
createIssues: boolean;
/** Do not open a pull request */
noPr: boolean;
/** Include latest failed CI build logs */
includeFixBuild: boolean;
/** Fetch and include contents from known URLs */
includeFetch: boolean;
/** Remaining prompt text after flags */
prompt: string;
}

const DIRECT_FLAGS = ['fix-build', 'fetch'] as const;
const TRIGGER_FLAGS = [
'full-history',
'create-issues',
'no-pr',
'fix-build',
'fetch',
] as const;

/**
* Extract prompt flags and remaining prompt text for direct or trigger-based prompts.
* @param input The raw input string containing flags and prompt text.
* @param isDirect Whether this is a direct prompt (true) or trigger-based (false).
* Extracts prompt flags and remaining prompt text for direct or trigger-based prompts.
*
* @param input - The raw input string containing flags and prompt text.
* @param isDirect - Whether this is a direct prompt (true) or trigger-based (false).
* @returns Parsed prompt options and cleaned prompt text.
*/
export function extractPromptFlags(
input: string,
isDirect: boolean,
): PromptFlagOptions {
const flagNames = isDirect
? ['fix-build', 'fetch']
: ['full-history', 'create-issues', 'no-pr', 'fix-build', 'fetch'];
const flagNames = isDirect ? DIRECT_FLAGS : TRIGGER_FLAGS;
const { flags, rest } = parseFlags(input, flagNames);

const {
'full-history': includeFullHistory = false,
'create-issues': createIssues = false,
'no-pr': noPr = false,
'fix-build': includeFixBuild = false,
fetch: includeFetch = false,
} = flags;

return {
includeFullHistory: !!flags['full-history'],
createIssues: !!flags['create-issues'],
noPr: !!flags['no-pr'],
includeFixBuild: !!flags['fix-build'],
includeFetch: !!flags['fetch'],
includeFullHistory,
createIssues,
noPr,
includeFixBuild,
includeFetch,
prompt: rest,
};
}