From aeb197ae05ef86e91de7e8c8390fe2226f2834d9 Mon Sep 17 00:00:00 2001 From: "Claude (claude-sonnet-4-5)" Date: Wed, 28 Jan 2026 04:59:33 +0000 Subject: [PATCH] Bug RHOAIENG-39115: Preserve command order from frontmatter Fixes issue where slash commands render alphabetically instead of the order specified in the custom workflow template. Changes: - Added 'order' field parsing from command frontmatter - Implemented sorting logic to honor order field in command list - Commands without order field default to MaxInt (appear at end) - Alphabetical fallback when orders are equal for consistency - Fully backward compatible with existing workflows The backend now sorts commands by their 'order' field before returning them to the frontend, ensuring commands display in the intended sequence rather than filesystem/alphabetical order. Commands can now specify order in frontmatter like: --- displayName: "Create RFE" description: "Start RFE creation process" order: 1 --- Co-Authored-By: Claude (claude-sonnet-4-5) --- components/backend/handlers/content.go | 31 ++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/components/backend/handlers/content.go b/components/backend/handlers/content.go index 0732cc67d..fe23bf1ed 100644 --- a/components/backend/handlers/content.go +++ b/components/backend/handlers/content.go @@ -9,6 +9,8 @@ import ( "os" "os/exec" "path/filepath" + "sort" + "strconv" "strings" "time" @@ -517,15 +519,44 @@ func ContentWorkflowMetadata(c *gin.Context) { shortCommand = commandName[lastDot+1:] } + // Parse order field from frontmatter, default to MaxInt32 for unordered commands + order := int(^uint(0) >> 1) // MaxInt + if orderStr := metadata["order"]; orderStr != "" { + if parsed, err := strconv.Atoi(orderStr); err == nil { + order = parsed + } + } + commands = append(commands, map[string]interface{}{ "id": commandName, "name": displayName, "description": metadata["description"], "slashCommand": "/" + shortCommand, "icon": metadata["icon"], + "order": order, }) } } + + // Sort commands by order field (ascending) + sort.Slice(commands, func(i, j int) bool { + iOrder, iOk := commands[i]["order"].(int) + jOrder, jOk := commands[j]["order"].(int) + if !iOk { + iOrder = int(^uint(0) >> 1) // MaxInt + } + if !jOk { + jOrder = int(^uint(0) >> 1) // MaxInt + } + // If orders are equal, sort alphabetically by id for consistent ordering + if iOrder == jOrder { + iID, _ := commands[i]["id"].(string) + jID, _ := commands[j]["id"].(string) + return iID < jID + } + return iOrder < jOrder + }) + log.Printf("ContentWorkflowMetadata: found %d commands", len(commands)) } else { log.Printf("ContentWorkflowMetadata: commands directory not found or unreadable: %v", err)