Skip to content

Commit 0c8cb15

Browse files
author
AndrewMorgan1
committed
Upgraded CLI program.cs for improved UX
1 parent 0123367 commit 0c8cb15

5 files changed

Lines changed: 61 additions & 26 deletions

File tree

src/PromptStream.AI.CLI/Commands/AnalyzeCommand.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using PromptStream.AI.CLI.Utils;
1+
using Flow.AI.Core.Models;
2+
using PromptStream.AI.CLI.Utils;
23
using PromptStream.AI.Context;
34
using PromptStream.AI.Integration;
45
using PromptStream.AI.Services;
@@ -38,7 +39,8 @@ public static Command Create()
3839
var service = new PromptStreamService(provider, context, modelClient);
3940

4041
// Perform analysis (returns tuple)
41-
var (validation, summary) = service.AnalyzePrompt(promptTemplate, variableMap);
42+
var templateObj = new PromptTemplate { Template = promptTemplate };
43+
var (validation, summary) = service.AnalyzePrompt(templateObj, variableMap);
4244

4345
if (!validation.IsValid)
4446
{

src/PromptStream.AI.CLI/Commands/BuildCommand.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using PromptStream.AI.Builders;
1+
using Flow.AI.Core.Models;
2+
using PromptStream.AI.Builders;
23
using PromptStream.AI.CLI.Utils;
34
using System.CommandLine;
45

@@ -27,7 +28,8 @@ public static Command Create()
2728
{
2829
var (promptTemplate, variableMap) = Program.LoadTemplateAndVars(template, vars);
2930
var builder = new PromptBuilder();
30-
var instance = builder.Build(promptTemplate, variableMap);
31+
var templateObj = new PromptTemplate { Template = promptTemplate };
32+
var instance = builder.Build(templateObj, variableMap);
3133

3234
ConsoleFormatter.Success("✅ Prompt built successfully:\n");
3335
Console.WriteLine(instance.RenderedText);

src/PromptStream.AI.CLI/Commands/GenerateCommand.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using PromptStream.AI.Integration;
66
using Flow.AI.Core.Interfaces;
77
using System.Diagnostics;
8+
using Flow.AI.Core.Models;
89

910
namespace PromptStream.AI.CLI.Commands
1011
{
@@ -43,7 +44,8 @@ public static Command Create()
4344
var service = new PromptStreamService(provider, ctxManager, modelClient);
4445

4546
var sw = Stopwatch.StartNew();
46-
var response = await service.GenerateAsync(promptTemplate, variableMap);
47+
var templateObj = new PromptTemplate { Template = promptTemplate };
48+
var response = await service.GenerateAsync(templateObj, variableMap);
4749
sw.Stop();
4850

4951
ConsoleFormatter.Success("✅ Generation complete:\n");

src/PromptStream.AI.CLI/Commands/ValidateCommand.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using PromptStream.AI.Services;
44
using PromptStream.AI.Context;
55
using Flow.AI.Core.Interfaces;
6+
using Flow.AI.Core.Models;
67

78
namespace PromptStream.AI.CLI.Commands
89
{
@@ -28,7 +29,8 @@ public static Command Create()
2829
var context = new PromptContextManager();
2930
var service = new PromptStreamService(provider, context);
3031

31-
var (instance, validation) = service.BuildAndValidate(promptTemplate, variableMap);
32+
var templateObj = new PromptTemplate { Template = promptTemplate };
33+
var (instance, validation) = service.BuildAndValidate(templateObj, variableMap);
3234

3335
if (validation.IsValid)
3436
ConsoleFormatter.Success($"✅ Valid prompt ({validation.TokenCount} tokens)\n");

src/PromptStream.AI.CLI/Program.cs

Lines changed: 47 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,74 @@
11
using System.CommandLine;
2-
using Flow.AI.Core.Models;
32
using PromptStream.AI.CLI.Commands;
3+
using PromptStream.AI.CLI.Utils;
44

55
namespace PromptStream.AI.CLI
66
{
7-
internal class Program
7+
internal static class Program
88
{
9-
static async Task<int> Main(string[] args)
9+
public static async Task<int> Main(string[] args)
1010
{
11-
var root = new RootCommand("PromptStream.AI CLI — build, validate, generate, and manage prompt contexts.");
11+
// Root command description
12+
var root = new RootCommand("PromptStream.AI CLI — Build, validate, analyze, and generate prompts interactively.");
1213

13-
// Register modular commands
14+
// Register all subcommands
1415
root.AddCommand(BuildCommand.Create());
1516
root.AddCommand(ValidateCommand.Create());
1617
root.AddCommand(GenerateCommand.Create());
17-
root.AddCommand(ContextCommand.Create());
1818
root.AddCommand(AnalyzeCommand.Create());
19+
root.AddCommand(ContextCommand.Create());
20+
21+
// Global verbose flag (optional, can be used later)
22+
var verboseOpt = new Option<bool>(
23+
aliases: new[] { "-v", "--verbose" },
24+
description: "Enable verbose output");
25+
root.AddGlobalOption(verboseOpt);
26+
27+
// Default handler: print help if no command is given
28+
root.SetHandler(() =>
29+
{
30+
ConsoleFormatter.Info("PromptStream.AI CLI — available commands:");
31+
Console.WriteLine(" build Render a prompt with variable substitution");
32+
Console.WriteLine(" validate Validate structure and token usage");
33+
Console.WriteLine(" analyze Analyze cost and token metrics");
34+
Console.WriteLine(" generate Build, validate, and run a model response");
35+
Console.WriteLine(" context Manage and summarize conversation context");
36+
Console.WriteLine("\nUse '--help' with any command for details.");
37+
});
1938

2039
return await root.InvokeAsync(args);
2140
}
2241

2342
/// <summary>
24-
/// Loads a prompt template and key-value variables from CLI input.
43+
/// Utility to load a prompt template and variable map.
44+
/// Used by Build, Validate, Generate, and Analyze commands.
2545
/// </summary>
26-
internal static (PromptTemplate, Dictionary<string, string>) LoadTemplateAndVars(string template, string[] vars)
46+
public static (string promptTemplate, Dictionary<string, string> variableMap) LoadTemplateAndVars(string templatePathOrText, string[]? vars)
2747
{
28-
string content = File.Exists(template)
29-
? File.ReadAllText(template)
30-
: template;
48+
string promptTemplate;
3149

32-
var variableMap = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
33-
foreach (var v in vars ?? Array.Empty<string>())
50+
// Try to treat the input as a file path first
51+
if (File.Exists(templatePathOrText))
3452
{
35-
var parts = v.Split('=', 2);
36-
if (parts.Length == 2)
37-
variableMap[parts[0]] = parts[1];
53+
promptTemplate = File.ReadAllText(templatePathOrText);
54+
}
55+
else
56+
{
57+
// Otherwise treat as inline text
58+
promptTemplate = templatePathOrText;
3859
}
3960

40-
var promptTemplate = new PromptTemplate
61+
var variableMap = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
62+
63+
if (vars != null)
4164
{
42-
Id = Path.GetFileNameWithoutExtension(template) ?? "inline-template",
43-
Template = content
44-
};
65+
foreach (var v in vars)
66+
{
67+
var parts = v.Split('=', 2);
68+
if (parts.Length == 2)
69+
variableMap[parts[0].Trim()] = parts[1].Trim();
70+
}
71+
}
4572

4673
return (promptTemplate, variableMap);
4774
}

0 commit comments

Comments
 (0)