agent-ecosystem/test/shared/utils/cliArgsParser.test.ts
iliya 48e5d9d6cd feat: introduce maintenance API for artifact reconciliation
- Added maintenance module to the agent-teams-controller, enabling the reconciliation of stale kanban entries and linked inbox comments.
- Implemented garbage collection logic in kanbanStore to remove invalid task references and clean up column orders.
- Updated controller to expose maintenance functionalities, allowing for better task and comment management.
- Enhanced tests to validate the new reconciliation process, ensuring idempotency and correctness in handling stale data.
- Integrated new CLI argument options for worktree and custom arguments in team launch and creation dialogs, improving user flexibility.
2026-03-07 18:48:57 +02:00

152 lines
4.8 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import {
extractFlagsFromHelp,
extractUserFlags,
parseCliArgs,
PROTECTED_CLI_FLAGS,
} from '@shared/utils/cliArgsParser';
describe('parseCliArgs', () => {
it('returns empty array for undefined', () => {
expect(parseCliArgs(undefined)).toEqual([]);
});
it('returns empty array for empty string', () => {
expect(parseCliArgs('')).toEqual([]);
});
it('splits simple flags and values', () => {
expect(parseCliArgs('--verbose --max-turns 5')).toEqual(['--verbose', '--max-turns', '5']);
});
it('handles double-quoted strings', () => {
expect(parseCliArgs('--message "hello world"')).toEqual(['--message', 'hello world']);
});
it('handles single-quoted strings', () => {
expect(parseCliArgs("--message 'it works'")).toEqual(['--message', 'it works']);
});
it('trims leading/trailing whitespace', () => {
expect(parseCliArgs(' --verbose ')).toEqual(['--verbose']);
});
it('handles multiple consecutive spaces', () => {
expect(parseCliArgs('--foo --bar baz')).toEqual(['--foo', '--bar', 'baz']);
});
it('handles tabs as separators', () => {
expect(parseCliArgs('--foo\t--bar')).toEqual(['--foo', '--bar']);
});
it('handles mixed quotes', () => {
expect(parseCliArgs(`--a "hello 'inner'" --b 'world "nested"'`)).toEqual([
'--a',
"hello 'inner'",
'--b',
'world "nested"',
]);
});
it('handles short flags', () => {
expect(parseCliArgs('-p "prompt text" -w name')).toEqual(['-p', 'prompt text', '-w', 'name']);
});
it('handles flag=value format', () => {
expect(parseCliArgs('--model=opus-4')).toEqual(['--model=opus-4']);
});
it('handles empty quoted strings', () => {
expect(parseCliArgs('--value ""')).toEqual(['--value', '']);
});
});
describe('extractFlagsFromHelp', () => {
const SAMPLE_HELP = `
Usage: claude [options] [prompt]
Options:
-p, --print Print response without interactive mode
-w, --worktree [name] Run in a git worktree
--model <model> Specify the model to use
--max-turns <number> Maximum conversation turns
--verbose Enable verbose logging
--dangerously-skip-permissions Skip permission checks
--input-format <format> Input format (text, stream-json)
--output-format <format> Output format
--no-session-persistence Don't persist session
-h, --help Display this help
-V, --version Display version
For more information, visit https://docs.anthropic.com
This is a non-interactive tool for automated workflows.
`;
it('extracts long flags', () => {
const flags = extractFlagsFromHelp(SAMPLE_HELP);
expect(flags.has('--model')).toBe(true);
expect(flags.has('--max-turns')).toBe(true);
expect(flags.has('--verbose')).toBe(true);
expect(flags.has('--dangerously-skip-permissions')).toBe(true);
expect(flags.has('--input-format')).toBe(true);
expect(flags.has('--output-format')).toBe(true);
expect(flags.has('--no-session-persistence')).toBe(true);
expect(flags.has('--worktree')).toBe(true);
});
it('extracts short flags', () => {
const flags = extractFlagsFromHelp(SAMPLE_HELP);
expect(flags.has('-p')).toBe(true);
expect(flags.has('-w')).toBe(true);
expect(flags.has('-h')).toBe(true);
expect(flags.has('-V')).toBe(true);
});
it('does not match hyphens in regular text', () => {
const flags = extractFlagsFromHelp(SAMPLE_HELP);
// "non-interactive" should not produce --non or -n from hyphenated words
expect(flags.has('--non')).toBe(false);
});
it('returns empty set for empty input', () => {
expect(extractFlagsFromHelp('').size).toBe(0);
});
});
describe('extractUserFlags', () => {
it('extracts flags from mixed input', () => {
expect(extractUserFlags('--verbose --max-turns 5 foo')).toEqual([
'--verbose',
'--max-turns',
]);
});
it('extracts short flags', () => {
expect(extractUserFlags('-p -w')).toEqual(['-p', '-w']);
});
it('returns empty for empty string', () => {
expect(extractUserFlags('')).toEqual([]);
});
it('returns empty when no flags present', () => {
expect(extractUserFlags('hello world')).toEqual([]);
});
});
describe('PROTECTED_CLI_FLAGS', () => {
it('contains expected flags', () => {
expect(PROTECTED_CLI_FLAGS.has('--input-format')).toBe(true);
expect(PROTECTED_CLI_FLAGS.has('--output-format')).toBe(true);
expect(PROTECTED_CLI_FLAGS.has('--mcp-config')).toBe(true);
expect(PROTECTED_CLI_FLAGS.has('--disallowedTools')).toBe(true);
expect(PROTECTED_CLI_FLAGS.has('--verbose')).toBe(true);
});
it('does not contain user-facing flags', () => {
expect(PROTECTED_CLI_FLAGS.has('--model')).toBe(false);
expect(PROTECTED_CLI_FLAGS.has('--effort')).toBe(false);
expect(PROTECTED_CLI_FLAGS.has('--worktree')).toBe(false);
});
});