-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProgram.cs
More file actions
111 lines (89 loc) · 3.57 KB
/
Program.cs
File metadata and controls
111 lines (89 loc) · 3.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// See https://aka.ms/new-console-template for more information
using GitHub.Copilot.SDK;
using MultiCliLauncher;
// Parse command-line arguments
var config = ArgumentParser.Parse(args);
if (config.ShowHelp)
{
ArgumentParser.PrintHelp();
return;
}
// Collect prompts from file and/or inline arguments
var prompts = new List<string>();
var modelToUse = config.Model;
// Read prompts from file if specified
if (!string.IsNullOrEmpty(config.PromptsFile))
{
if (!File.Exists(config.PromptsFile))
{
Console.Error.WriteLine($"Error: Prompts file not found: {config.PromptsFile}");
Environment.Exit(1);
}
var fileResult = await PromptFileReader.ReadPromptsAsync(config.PromptsFile);
prompts.AddRange(fileResult.Prompts);
// Use model from file if specified (command-line takes precedence if explicitly set)
if (fileResult.ModelOverride != null && config.Model == "Claude Opus 4.5")
{
modelToUse = fileResult.ModelOverride;
}
}
// Add inline prompts
prompts.AddRange(config.InlinePrompts);
// Validate we have at least one prompt
if (prompts.Count == 0)
{
Console.Error.WriteLine("Error: No prompts provided. Use -f <file> or pass prompts as arguments.");
Console.Error.WriteLine("Run with --help for usage information.");
Environment.Exit(1);
}
// Display parsed configuration for validation
Console.WriteLine($"Model: {modelToUse}");
Console.WriteLine($"Max Parallel: {config.MaxParallel}");
Console.WriteLine($"Timeout: {config.TimeoutMinutes} minutes");
Console.WriteLine($"Output Directory: {config.OutputDir}");
if (config.SkillDirectories.Count > 0)
{
Console.WriteLine($"Skill Directories: {string.Join(", ", config.SkillDirectories)}");
}
Console.WriteLine($"Total Prompts: {prompts.Count}");
for (int i = 0; i < prompts.Count; i++)
{
var preview = prompts[i].Length > 50
? prompts[i][..50].Replace("\n", " ") + "..."
: prompts[i].Replace("\n", " ");
Console.WriteLine($" [{i + 1}] {preview}");
}
Console.WriteLine();
// Set up concurrency throttling
var throttle = new SemaphoreSlim(config.MaxParallel, config.MaxParallel);
var timeout = TimeSpan.FromMinutes(config.TimeoutMinutes);
// Prepare skill directories (expand paths)
var skillDirs = config.SkillDirectories.Count > 0
? config.SkillDirectories.Select(Path.GetFullPath).ToList()
: null;
// Set up output coordination
await using var coordinator = new OutputCoordinator(prompts.Count);
// Create client and executor
await using var client = new CopilotClient();
var executor = new PromptExecutor(client, modelToUse, coordinator, throttle, timeout, skillDirs);
// Start the producer task (executes all prompts in parallel)
var producerTask = executor.ExecuteAllAsync(prompts);
// Start consumer (buffers and prints completed tasks)
var consumer = new OutputConsumer(coordinator);
var consumerTask = consumer.ConsumeAsync();
// Wait for producers to finish
await producerTask;
// Wait for consumer to finish and get result
var result = await consumerTask;
// Print summary
Console.WriteLine();
Console.WriteLine($"Completed: {result.SuccessCount} successful, {result.ErrorCount} failed");
// Write markdown output to file
var outputDir = Path.GetFullPath(config.OutputDir);
Directory.CreateDirectory(outputDir);
var timestamp = DateTime.Now.ToString("yyyy-MM-dd-HHmmss");
var outputFileName = $"Multi-CLI-Launcher-Output-{timestamp}.md";
var outputPath = Path.Combine(outputDir, outputFileName);
await File.WriteAllTextAsync(outputPath, result.MarkdownContent.ToString());
Console.WriteLine();
Console.WriteLine($"Output saved to: {outputPath}");