From cac4c956be380784da723894a2c7cd599c7194aa Mon Sep 17 00:00:00 2001 From: mercersoft Date: Thu, 23 Oct 2025 13:50:14 -0700 Subject: [PATCH 1/4] Added /info slash command that will display build information as well as the path to the AGENTS.md file loaded at startup --- src/cycod/CommandLineCommands/ChatCommand.cs | 125 +++++++++++++++++++ 1 file changed, 125 insertions(+) diff --git a/src/cycod/CommandLineCommands/ChatCommand.cs b/src/cycod/CommandLineCommands/ChatCommand.cs index 67e96cbc..ce818b6c 100644 --- a/src/cycod/CommandLineCommands/ChatCommand.cs +++ b/src/cycod/CommandLineCommands/ChatCommand.cs @@ -281,6 +281,10 @@ private string GetSystemPromptAdds() { skipAssistant = HandleHelpCommand(); } + else if (userPrompt == "/info") + { + skipAssistant = HandleInfoCommand(); + } else if (_cycoDmdCommandHandler?.IsCommand(userPrompt) == true) { skipAssistant = await HandleCycoDmdCommand(chat, userPrompt); @@ -354,6 +358,7 @@ private bool HandleHelpCommand() helpBuilder.AppendLine(" /save Save chat history to file"); helpBuilder.AppendLine(" /clear Clear chat history"); helpBuilder.AppendLine(" /cost Show token usage statistics"); + helpBuilder.AppendLine(" /info Display program information"); helpBuilder.AppendLine(" /help Show this help message"); helpBuilder.AppendLine(); @@ -429,6 +434,126 @@ private bool HandleHelpCommand() return true; } + private bool HandleInfoCommand() + { + var programNameUppercase = ProgramInfo.Name.ToUpper(); + var programDescription = ProgramInfo.Description; + var version = VersionInfo.GetVersion(); + + var bannerText = $"{programNameUppercase} - {programDescription}\n" + + "Copyright(c) 2025, Rob Chambers. All rights reserved.\n\n"; + ConsoleHelpers.WriteLine(bannerText, overrideQuiet: true); + + // Parse and display version components + var versionInfo = ParseVersionString(version); + ConsoleHelpers.WriteLine($"Version: {versionInfo.BaseVersion}", overrideQuiet: true); + if (versionInfo.IsDevBuild && !string.IsNullOrEmpty(versionInfo.Developer)) + { + ConsoleHelpers.WriteLine($"Developer: {versionInfo.Developer}", overrideQuiet: true); + } + if (!string.IsNullOrEmpty(versionInfo.BuildDate)) + { + ConsoleHelpers.WriteLine($"Built: {versionInfo.BuildDate}", overrideQuiet: true); + } + if (!string.IsNullOrEmpty(versionInfo.CommitHash)) + { + ConsoleHelpers.WriteLine($"Commit: {versionInfo.CommitHash}", overrideQuiet: true); + } + ConsoleHelpers.WriteLine("", overrideQuiet: true); + + // Display AGENTS.md file location if present + var agentsFile = AgentsFileHelpers.FindAgentsFile(); + if (agentsFile != null) + { + ConsoleHelpers.WriteLine($"AGENTS.md: {agentsFile}\n", overrideQuiet: true); + } + else + { + ConsoleHelpers.WriteLine("AGENTS.md: No AGENTS.md file found\n", overrideQuiet: true); + } + + return true; + } + + private (string BaseVersion, bool IsDevBuild, string Developer, string BuildDate, string CommitHash) ParseVersionString(string version) + { + // Example: 1.0.0-DEV-phs-20251023.1319+4d348df87afc2a42e460aaa3d4056acee19894c4 + var baseVersion = version; + var isDevBuild = false; + var developer = string.Empty; + var buildDate = string.Empty; + var commitHash = string.Empty; + + try + { + // Extract commit hash (after +) + var plusIndex = version.IndexOf('+'); + if (plusIndex >= 0) + { + commitHash = version.Substring(plusIndex + 1); + if (commitHash.Length > 8) commitHash = commitHash.Substring(0, 8); // Short hash + version = version.Substring(0, plusIndex); + } + + // Split by dash to get parts + var parts = version.Split('-'); + if (parts.Length > 0) + { + baseVersion = parts[0]; // 1.0.0 + } + + // Check if this is a DEV build (typically 2nd part) + if (parts.Length >= 2) + { + isDevBuild = parts[1].Equals("DEV", StringComparison.OrdinalIgnoreCase); + } + + // Look for developer name (typically 3rd part, after version and DEV/config) + if (parts.Length >= 3) + { + developer = parts[2]; // phs + } + + // Look for date/time (typically 4th part) + if (parts.Length >= 4) + { + var dateTimePart = parts[3]; // 20251023.1319 + var dotIndex = dateTimePart.IndexOf('.'); + + if (dotIndex >= 0) + { + var datePart = dateTimePart.Substring(0, dotIndex); // 20251023 + var timePart = dateTimePart.Substring(dotIndex + 1); // 1319 + + // Parse date: YYYYMMDD + if (datePart.Length == 8) + { + var year = datePart.Substring(0, 4); + var month = datePart.Substring(4, 2); + var day = datePart.Substring(6, 2); + + // Parse time: HHMM + var time = string.Empty; + if (timePart.Length == 4) + { + var hour = timePart.Substring(0, 2); + var minute = timePart.Substring(2, 2); + time = $" {hour}:{minute}"; + } + + buildDate = $"{year}-{month}-{day}{time}"; + } + } + } + } + catch + { + // If parsing fails, just return what we have + } + + return (baseVersion, isDevBuild, developer, buildDate, commitHash); + } + private async Task CompleteChatStreamingAsync( FunctionCallingChat chat, string userPrompt, From ab4e93b2b84ff15169ed8f085d1dbc70dcb7b722 Mon Sep 17 00:00:00 2001 From: Philipp Schmid Date: Thu, 23 Oct 2025 13:57:51 -0700 Subject: [PATCH 2/4] Update src/cycod/CommandLineCommands/ChatCommand.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/cycod/CommandLineCommands/ChatCommand.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cycod/CommandLineCommands/ChatCommand.cs b/src/cycod/CommandLineCommands/ChatCommand.cs index ce818b6c..faa88dc8 100644 --- a/src/cycod/CommandLineCommands/ChatCommand.cs +++ b/src/cycod/CommandLineCommands/ChatCommand.cs @@ -441,7 +441,7 @@ private bool HandleInfoCommand() var version = VersionInfo.GetVersion(); var bannerText = $"{programNameUppercase} - {programDescription}\n" + - "Copyright(c) 2025, Rob Chambers. All rights reserved.\n\n"; + "Copyright (c) 2025, Rob Chambers. All rights reserved.\n\n"; ConsoleHelpers.WriteLine(bannerText, overrideQuiet: true); // Parse and display version components From f58cca41813e61e0ec4b24c8684e6f63e10b72d6 Mon Sep 17 00:00:00 2001 From: Philipp Schmid Date: Thu, 23 Oct 2025 13:58:01 -0700 Subject: [PATCH 3/4] Update src/cycod/CommandLineCommands/ChatCommand.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/cycod/CommandLineCommands/ChatCommand.cs | 80 ++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/src/cycod/CommandLineCommands/ChatCommand.cs b/src/cycod/CommandLineCommands/ChatCommand.cs index faa88dc8..e36910e0 100644 --- a/src/cycod/CommandLineCommands/ChatCommand.cs +++ b/src/cycod/CommandLineCommands/ChatCommand.cs @@ -475,6 +475,86 @@ private bool HandleInfoCommand() return true; } + /// + /// Parses a version string into its components. + /// + /// + /// Expected version string format: + /// + /// {baseVersion}[-DEV-{developer}-{buildDate}][+{commitHash}] + /// + /// + /// + /// Components: + /// + /// + /// + /// baseVersion: The main version number (e.g., "1.0.0"). + /// + /// + /// + /// + /// -DEV: Optional marker indicating a development build. + /// + /// + /// + /// + /// {developer}: Optional developer identifier (e.g., "phs"). + /// + /// + /// + /// + /// {buildDate}: Optional build date and time in the format "yyyyMMdd.HHmm" (e.g., "20251023.1319"). + /// + /// + /// + /// + /// +{commitHash}: Optional commit hash (e.g., "4d348df87afc2a42e460aaa3d4056acee19894c4"). + /// + /// + /// + /// + /// + /// Parsing logic: + /// + /// + /// + /// If the version string contains a '+', the substring after '+' is treated as the commit hash. + /// + /// + /// + /// + /// The main part before '+' is split by '-', and if it contains "DEV", it is considered a development build. + /// + /// + /// + /// + /// If present, the developer and build date are extracted from the segments following "DEV". + /// + /// + /// + /// + /// The base version is always the first segment. + /// + /// + /// + /// + /// + /// Example: + /// + /// 1.0.0-DEV-phs-20251023.1319+4d348df87afc2a42e460aaa3d4056acee19894c4 + /// + /// + /// + /// The version string to parse. + /// + /// A tuple containing: + /// - BaseVersion: The main version number. + /// - IsDevBuild: True if this is a development build. + /// - Developer: The developer identifier, if present. + /// - BuildDate: The build date, if present. + /// - CommitHash: The commit hash, if present. + /// private (string BaseVersion, bool IsDevBuild, string Developer, string BuildDate, string CommitHash) ParseVersionString(string version) { // Example: 1.0.0-DEV-phs-20251023.1319+4d348df87afc2a42e460aaa3d4056acee19894c4 From a0d26ad480219adc3ba3522ebf7a02962bc3f3d4 Mon Sep 17 00:00:00 2001 From: Philipp Schmid Date: Thu, 23 Oct 2025 13:58:13 -0700 Subject: [PATCH 4/4] Update src/cycod/CommandLineCommands/ChatCommand.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/cycod/CommandLineCommands/ChatCommand.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cycod/CommandLineCommands/ChatCommand.cs b/src/cycod/CommandLineCommands/ChatCommand.cs index e36910e0..94e17968 100644 --- a/src/cycod/CommandLineCommands/ChatCommand.cs +++ b/src/cycod/CommandLineCommands/ChatCommand.cs @@ -626,9 +626,10 @@ private bool HandleInfoCommand() } } } - catch + catch (Exception ex) { // If parsing fails, just return what we have + ConsoleHelpers.LogException(ex, "Failed to parse version string", showToUser: false); } return (baseVersion, isDevBuild, developer, buildDate, commitHash);