Commit f17d5bd

bryfry <bryon@fryer.io>
2025-09-18 08:38:44
fmt
1 parent 6aa053e
cmd/cache.go
@@ -127,4 +127,4 @@ func formatBytes(bytes int64) string {
 		exp++
 	}
 	return fmt.Sprintf("%.1f %cB", float64(bytes)/float64(div), "KMGTPE"[exp])
-}
\ No newline at end of file
+}
cmd/callbacks.go
@@ -222,12 +222,12 @@ func runCallbacks(cmd *cobra.Command, args []string) error {
 
 	// Define columns with priorities (1=highest, higher numbers can be dropped)
 	columns := []ColumnInfo{
-		{Header: "ID", Number: 1, MinWidth: 3, MaxWidth: 6, Priority: 1},         // Always show
-		{Header: "TYPE", Number: 2, MinWidth: 6, MaxWidth: 10, Priority: 3},      // High priority
-		{Header: "HOST", Number: 3, MinWidth: 8, MaxWidth: 16, Priority: 2},      // Very important
-		{Header: "USER", Number: 4, MinWidth: 6, MaxWidth: 12, Priority: 4},      // Important
-		{Header: "PROCESS", Number: 5, MinWidth: 8, MaxWidth: 12, Priority: 6},   // Can drop
-		{Header: "PID", Number: 6, MinWidth: 3, MaxWidth: 6, Priority: 7},        // Can drop
+		{Header: "ID", Number: 1, MinWidth: 3, MaxWidth: 6, Priority: 1},       // Always show
+		{Header: "TYPE", Number: 2, MinWidth: 6, MaxWidth: 10, Priority: 3},    // High priority
+		{Header: "HOST", Number: 3, MinWidth: 8, MaxWidth: 16, Priority: 2},    // Very important
+		{Header: "USER", Number: 4, MinWidth: 6, MaxWidth: 12, Priority: 4},    // Important
+		{Header: "PROCESS", Number: 5, MinWidth: 8, MaxWidth: 12, Priority: 6}, // Can drop
+		{Header: "PID", Number: 6, MinWidth: 3, MaxWidth: 6, Priority: 7},      // Can drop
 		{Header: "LAST CHECKIN", Number: 7, MinWidth: 8, MaxWidth: 10, Priority: 5},
 		{Header: "DESCRIPTION", Number: 8, MinWidth: 10, MaxWidth: 25, Priority: 8}, // First to drop
 	}
@@ -261,4 +261,4 @@ func runCallbacks(cmd *cobra.Command, args []string) error {
 
 	t.Render()
 	return nil
-}
\ No newline at end of file
+}
cmd/files.go
@@ -32,7 +32,6 @@ var filesCmd = &cobra.Command{
 	RunE:    runFilesList, // Default to list command
 }
 
-
 var filesDownloadCmd = &cobra.Command{
 	Use:   "download <file_uuid_or_task_id>",
 	Short: "Download a file by UUID or task ID",
@@ -127,15 +126,15 @@ func runFilesList(cmd *cobra.Command, args []string) error {
 
 	// Define columns with priorities for responsive display
 	columns := []ColumnInfo{
-		{Header: "UUID", Number: 1, MinWidth: 8, MaxWidth: 36, Priority: 5},        // Can drop on small screens
-		{Header: "TYPE", Number: 2, MinWidth: 6, MaxWidth: 10, Priority: 3},        // Important
-		{Header: "FILENAME", Number: 3, MinWidth: 10, MaxWidth: 30, Priority: 1},   // Never drop - most important
+		{Header: "UUID", Number: 1, MinWidth: 8, MaxWidth: 36, Priority: 5},         // Can drop on small screens
+		{Header: "TYPE", Number: 2, MinWidth: 6, MaxWidth: 10, Priority: 3},         // Important
+		{Header: "FILENAME", Number: 3, MinWidth: 10, MaxWidth: 30, Priority: 1},    // Never drop - most important
 		{Header: "REMOTE PATH", Number: 4, MinWidth: 12, MaxWidth: 40, Priority: 6}, // First to drop
-		{Header: "HOST", Number: 5, MinWidth: 8, MaxWidth: 20, Priority: 4},        // Medium priority
-		{Header: "SIZE", Number: 6, MinWidth: 6, MaxWidth: 10, Priority: 3},        // Important
-		{Header: "COMPLETE", Number: 7, MinWidth: 6, MaxWidth: 8, Priority: 2},     // High priority
-		{Header: "TASK", Number: 8, MinWidth: 4, MaxWidth: 8, Priority: 5},         // Can drop
-		{Header: "TIMESTAMP", Number: 9, MinWidth: 12, MaxWidth: 16, Priority: 7},  // First to drop
+		{Header: "HOST", Number: 5, MinWidth: 8, MaxWidth: 20, Priority: 4},         // Medium priority
+		{Header: "SIZE", Number: 6, MinWidth: 6, MaxWidth: 10, Priority: 3},         // Important
+		{Header: "COMPLETE", Number: 7, MinWidth: 6, MaxWidth: 8, Priority: 2},      // High priority
+		{Header: "TASK", Number: 8, MinWidth: 4, MaxWidth: 8, Priority: 5},          // Can drop
+		{Header: "TIMESTAMP", Number: 9, MinWidth: 12, MaxWidth: 16, Priority: 7},   // First to drop
 	}
 
 	// Configure table for current terminal width
@@ -362,4 +361,4 @@ func extractUUIDFromTaskResponse(response string) []string {
 	}
 
 	return uuids
-}
\ No newline at end of file
+}
cmd/grep.go
@@ -59,7 +59,6 @@ func init() {
 	grepCmd.Flags().BoolVar(&grepRaw, "raw", false, "Display raw output with grep -R style single-line file delimiters")
 }
 
-
 func runGrep(cmd *cobra.Command, args []string) error {
 	if err := validateConfig(); err != nil {
 		return err
@@ -244,7 +243,6 @@ func runGrep(cmd *cobra.Command, args []string) error {
 	return nil
 }
 
-
 func showRawMatches(matches []rawMatch) {
 	for i, match := range matches {
 		// Format like tail -f: ==> filename <==
@@ -286,11 +284,11 @@ func showMatchingTasksTable(tasks []mythic.Task) {
 
 	// Define columns with priorities (1=highest, higher numbers can be dropped)
 	columns := []ColumnInfo{
-		{Header: "TASK ID", Number: 1, MinWidth: 6, MaxWidth: 8, Priority: 1},   // Always show
-		{Header: "COMMAND", Number: 2, MinWidth: 8, MaxWidth: 12, Priority: 2},  // High priority
-		{Header: "PARAMS", Number: 3, MinWidth: 10, MaxWidth: 30, Priority: 5},  // Can drop
-		{Header: "STATUS", Number: 4, MinWidth: 6, MaxWidth: 10, Priority: 3},   // Important
-		{Header: "CALLBACK", Number: 5, MinWidth: 6, MaxWidth: 8, Priority: 4},  // Important
+		{Header: "TASK ID", Number: 1, MinWidth: 6, MaxWidth: 8, Priority: 1},     // Always show
+		{Header: "COMMAND", Number: 2, MinWidth: 8, MaxWidth: 12, Priority: 2},    // High priority
+		{Header: "PARAMS", Number: 3, MinWidth: 10, MaxWidth: 30, Priority: 5},    // Can drop
+		{Header: "STATUS", Number: 4, MinWidth: 6, MaxWidth: 10, Priority: 3},     // Important
+		{Header: "CALLBACK", Number: 5, MinWidth: 6, MaxWidth: 8, Priority: 4},    // Important
 		{Header: "TIMESTAMP", Number: 6, MinWidth: 10, MaxWidth: 14, Priority: 6}, // First to drop
 	}
 
@@ -462,4 +460,4 @@ func getCachedTasks(taskCache *cache.TaskCache) []mythic.Task {
 	}
 
 	return tasks
-}
\ No newline at end of file
+}
cmd/grep_test.go
@@ -141,4 +141,4 @@ func TestGrepCommandStringConstruction(t *testing.T) {
 			}
 		})
 	}
-}
\ No newline at end of file
+}
cmd/interact.go
@@ -49,10 +49,10 @@ func runInteract(cmd *cobra.Command, args []string) error {
 		agentType = "agent" // fallback if payload type is not available
 	}
 
-	fmt.Printf("Interacting with callback %d (%s@%s - %s [%s])\n", 
-		targetCallback.DisplayID, 
-		targetCallback.User, 
-		targetCallback.Host, 
+	fmt.Printf("Interacting with callback %d (%s@%s - %s [%s])\n",
+		targetCallback.DisplayID,
+		targetCallback.User,
+		targetCallback.Host,
 		targetCallback.ProcessName,
 		agentType)
 	fmt.Println("Type 'exit' to quit the interactive session")
@@ -116,4 +116,4 @@ func executeCommand(ctx context.Context, client *mythic.Client, callbackID int,
 		fmt.Printf("\nTask completed with status: %s\n", updatedTask.Status)
 	}
 	return nil
-}
\ No newline at end of file
+}
cmd/payload.go
@@ -80,7 +80,7 @@ func showPayloadList(ctx context.Context, client *mythic.Client) error {
 
 	// Define columns with priorities (1=highest, higher numbers can be dropped)
 	columns := []ColumnInfo{
-		{Header: "ID", Number: 1, MinWidth: 3, MaxWidth: 6, Priority: 1},             // Always show
+		{Header: "ID", Number: 1, MinWidth: 3, MaxWidth: 6, Priority: 1},            // Always show
 		{Header: "TYPE", Number: 2, MinWidth: 6, MaxWidth: 10, Priority: 2},         // High priority
 		{Header: "DESCRIPTION", Number: 3, MinWidth: 10, MaxWidth: 20, Priority: 5}, // Can drop
 		{Header: "FILENAME", Number: 4, MinWidth: 8, MaxWidth: 16, Priority: 3},     // Important
@@ -244,4 +244,4 @@ func getValueOrDefault(value, defaultValue string) string {
 		return defaultValue
 	}
 	return value
-}
\ No newline at end of file
+}
cmd/root.go
@@ -115,7 +115,7 @@ func configureTableForTerminal(t table.Writer, columns []ColumnInfo) *DynamicTab
 	for i, col := range visibleColumns {
 		headers = append(headers, col.Header)
 		configs = append(configs, table.ColumnConfig{
-			Number:           i + 1, // Use sequential numbers for visible columns
+			Number:           i + 1,           // Use sequential numbers for visible columns
 			WidthMin:         columnWidths[i], // Force minimum width
 			WidthMax:         columnWidths[i], // Force maximum width
 			WidthMaxEnforcer: truncateWithEllipsis,
@@ -260,4 +260,3 @@ func truncateWithEllipsis(col string, maxLen int) string {
 	}
 	return col[:maxLen-3] + "..."
 }
-
cmd/task.go
@@ -229,4 +229,4 @@ func runTask(cmd *cobra.Command, args []string) error {
 	}
 
 	return nil
-}
\ No newline at end of file
+}
cmd/task_list.go
@@ -111,20 +111,20 @@ func runTaskList(cmd *cobra.Command, args []string) error {
 	if showingAllCallbacks {
 		// Define columns with priorities for all callbacks view
 		columns = []ColumnInfo{
-			{Header: "TASK ID", Number: 1, MinWidth: 6, MaxWidth: 8, Priority: 1},    // Always show
-			{Header: "CALLBACK", Number: 2, MinWidth: 6, MaxWidth: 8, Priority: 2},  // High priority
-			{Header: "COMMAND", Number: 3, MinWidth: 8, MaxWidth: 15, Priority: 3},  // Important
-			{Header: "PARAMS", Number: 4, MinWidth: 10, MaxWidth: 40, Priority: 5},  // Can drop
-			{Header: "STATUS", Number: 5, MinWidth: 8, MaxWidth: 12, Priority: 4},   // Important
+			{Header: "TASK ID", Number: 1, MinWidth: 6, MaxWidth: 8, Priority: 1},     // Always show
+			{Header: "CALLBACK", Number: 2, MinWidth: 6, MaxWidth: 8, Priority: 2},    // High priority
+			{Header: "COMMAND", Number: 3, MinWidth: 8, MaxWidth: 15, Priority: 3},    // Important
+			{Header: "PARAMS", Number: 4, MinWidth: 10, MaxWidth: 40, Priority: 5},    // Can drop
+			{Header: "STATUS", Number: 5, MinWidth: 8, MaxWidth: 12, Priority: 4},     // Important
 			{Header: "TIMESTAMP", Number: 6, MinWidth: 12, MaxWidth: 19, Priority: 6}, // First to drop
 		}
 	} else {
 		// Define columns with priorities for single callback view
 		columns = []ColumnInfo{
-			{Header: "TASK ID", Number: 1, MinWidth: 6, MaxWidth: 8, Priority: 1},    // Always show
-			{Header: "COMMAND", Number: 2, MinWidth: 8, MaxWidth: 15, Priority: 2},   // High priority
-			{Header: "PARAMS", Number: 3, MinWidth: 10, MaxWidth: 50, Priority: 4},   // Can drop
-			{Header: "STATUS", Number: 4, MinWidth: 8, MaxWidth: 12, Priority: 3},    // Important
+			{Header: "TASK ID", Number: 1, MinWidth: 6, MaxWidth: 8, Priority: 1},     // Always show
+			{Header: "COMMAND", Number: 2, MinWidth: 8, MaxWidth: 15, Priority: 2},    // High priority
+			{Header: "PARAMS", Number: 3, MinWidth: 10, MaxWidth: 50, Priority: 4},    // Can drop
+			{Header: "STATUS", Number: 4, MinWidth: 8, MaxWidth: 12, Priority: 3},     // Important
 			{Header: "TIMESTAMP", Number: 5, MinWidth: 12, MaxWidth: 19, Priority: 5}, // First to drop
 		}
 	}
@@ -172,4 +172,4 @@ func runTaskList(cmd *cobra.Command, args []string) error {
 	t.Render()
 
 	return nil
-}
\ No newline at end of file
+}
cmd/task_view.go
@@ -150,4 +150,4 @@ func runTaskView(cmd *cobra.Command, args []string) error {
 	}
 
 	return nil
-}
\ No newline at end of file
+}
cmd/upload.go
@@ -173,4 +173,4 @@ func runUpload(cmd *cobra.Command, args []string) error {
 	}
 
 	return nil
-}
\ No newline at end of file
+}
pkg/cache/cache.go
@@ -82,7 +82,6 @@ type CachedTask struct {
 	ServerURL string       `json:"server_url"`
 }
 
-
 // generateCacheKey creates a unique cache key for a task
 func (tc *TaskCache) generateCacheKey(taskID int, serverURL string) string {
 	// Create a hash based on task ID and server URL to ensure uniqueness
@@ -91,7 +90,6 @@ func (tc *TaskCache) generateCacheKey(taskID int, serverURL string) string {
 	return fmt.Sprintf("task_%d_%x.json", taskID, h.Sum(nil)[:8])
 }
 
-
 // GetCachedTask retrieves a cached task if it exists and is for a completed task
 func (tc *TaskCache) GetCachedTask(taskID int, serverURL string) (*mythic.Task, bool) {
 	cacheKey := tc.generateCacheKey(taskID, serverURL)
@@ -238,4 +236,3 @@ func (tc *TaskCache) ClearCache() error {
 
 	return nil
 }
-
pkg/mythic/api/callbacks.go
@@ -25,4 +25,4 @@ func FindActiveCallback(ctx context.Context, client MythicClient, callbackID int
 // ValidateCallbackExists verifies that a callback exists and is accessible
 func ValidateCallbackExists(ctx context.Context, client MythicClient, callbackID int) (*mythic.Callback, error) {
 	return FindActiveCallback(ctx, client, callbackID)
-}
\ No newline at end of file
+}
pkg/mythic/api/callbacks_test.go
@@ -37,11 +37,11 @@ func (m *MockClient) GetAllTasksWithResponses(ctx context.Context, limit int) ([
 
 func TestFindActiveCallback(t *testing.T) {
 	tests := []struct {
-		name        string
-		callbacks   []mythic.Callback
-		callbackID  int
-		expectErr   bool
-		expectedID  int
+		name       string
+		callbacks  []mythic.Callback
+		callbackID int
+		expectErr  bool
+		expectedID int
 	}{
 		{
 			name: "callback found",
@@ -121,4 +121,4 @@ func TestValidateCallbackExists(t *testing.T) {
 	if result != nil {
 		t.Error("Expected nil result for non-existent callback")
 	}
-}
\ No newline at end of file
+}
pkg/mythic/api/constants.go
@@ -28,7 +28,7 @@ const (
 
 // UUID format constants
 const (
-	UUIDLength         = 36
+	UUIDLength          = 36
 	UUIDLengthNoHyphens = 32
-	UUIDDisplayLength  = 8 // Number of characters to show in truncated displays
-)
\ No newline at end of file
+	UUIDDisplayLength   = 8 // Number of characters to show in truncated displays
+)
pkg/mythic/api/constants_test.go
@@ -44,4 +44,4 @@ func TestConstants(t *testing.T) {
 	if UUIDDisplayLength != 8 {
 		t.Errorf("Expected UUIDDisplayLength to be 8, got %d", UUIDDisplayLength)
 	}
-}
\ No newline at end of file
+}
pkg/mythic/api/interfaces.go
@@ -15,4 +15,4 @@ type MythicClient interface {
 }
 
 // Ensure that the real Client implements the interface
-var _ MythicClient = (*mythic.Client)(nil)
\ No newline at end of file
+var _ MythicClient = (*mythic.Client)(nil)
pkg/mythic/api/tasks.go
@@ -62,4 +62,4 @@ func ExecuteTaskAndWait(ctx context.Context, client MythicClient, callbackID int
 
 	// Poll for response
 	return PollTaskResponse(ctx, client, task.ID, config)
-}
\ No newline at end of file
+}
pkg/mythic/api/tasks_test.go
@@ -169,4 +169,4 @@ func TestExecuteTaskAndWait_Timeout(t *testing.T) {
 	if result != nil {
 		t.Error("Expected nil result on timeout")
 	}
-}
\ No newline at end of file
+}
pkg/mythic/client.go
@@ -43,16 +43,16 @@ type Callback struct {
 }
 
 type Task struct {
-	ID            int    `json:"id"`
-	DisplayID     int    `json:"display_id"`
-	Command       string `json:"command"`
-	Params        string `json:"params"`
-	Status        string `json:"status"`
-	Response      string `json:"response,omitempty"`
-	CallbackID    int    `json:"callback_id"`
-	OperatorID    int    `json:"operator_id"`
-	Timestamp     string `json:"timestamp,omitempty"`
-	Completed     bool   `json:"completed"`
+	ID         int    `json:"id"`
+	DisplayID  int    `json:"display_id"`
+	Command    string `json:"command"`
+	Params     string `json:"params"`
+	Status     string `json:"status"`
+	Response   string `json:"response,omitempty"`
+	CallbackID int    `json:"callback_id"`
+	OperatorID int    `json:"operator_id"`
+	Timestamp  string `json:"timestamp,omitempty"`
+	Completed  bool   `json:"completed"`
 }
 
 type File struct {
@@ -97,9 +97,9 @@ type Payload struct {
 	PayloadTypeName  string `json:"payloadtype_name"`
 
 	// File info
-	FileID       int    `json:"file_id"`
-	Filename     string `json:"filename"`
-	AgentFileID  string `json:"agent_file_id"`
+	FileID      int    `json:"file_id"`
+	Filename    string `json:"filename"`
+	AgentFileID string `json:"agent_file_id"`
 
 	// C2 Profiles
 	C2Profiles []string `json:"c2_profiles"`
@@ -144,30 +144,30 @@ func isBase64(s string) bool {
 	if len(s) < 4 {
 		return false
 	}
-	
+
 	// Check if it matches base64 pattern
 	base64Regex := regexp.MustCompile(`^[A-Za-z0-9+/]*={0,2}$`)
 	if !base64Regex.MatchString(s) {
 		return false
 	}
-	
+
 	// Try to decode
 	decoded, err := base64.StdEncoding.DecodeString(s)
 	if err != nil {
 		return false
 	}
-	
+
 	// If decoded content is not valid UTF-8, it's likely binary data
 	if !utf8.Valid(decoded) {
 		return true
 	}
-	
-	// If it's valid UTF-8 but the original string looks like base64 
+
+	// If it's valid UTF-8 but the original string looks like base64
 	// and is significantly longer than the decoded version, it's likely base64
 	if float64(len(s)) > float64(len(decoded))*1.2 {
 		return true
 	}
-	
+
 	return false
 }
 
@@ -182,24 +182,24 @@ func decodeResponseText(responseText string) string {
 		// If it's binary data, return a placeholder message
 		return fmt.Sprintf("[Binary data: %d bytes]", len(decoded))
 	}
-	
+
 	// If base64 decode fails, return original text
 	return responseText
 }
 
 func (c *Client) GetCallbacks(ctx context.Context) ([]Callback, error) {
 	req := graphql.NewRequest(GetCallbacks)
-	
+
 	req.Header.Set("apitoken", c.token)
-	
+
 	var resp struct {
 		Callback []Callback `json:"callback"`
 	}
-	
+
 	if err := c.client.Run(ctx, req, &resp); err != nil {
 		return nil, fmt.Errorf("failed to get callbacks: %w", err)
 	}
-	
+
 	return resp.Callback, nil
 }
 
@@ -208,26 +208,26 @@ func (c *Client) GetActiveCallbacks(ctx context.Context) ([]Callback, error) {
 	if err != nil {
 		return nil, err
 	}
-	
+
 	var active []Callback
 	for _, callback := range callbacks {
 		if callback.Active {
 			active = append(active, callback)
 		}
 	}
-	
+
 	return active, nil
 }
 
 func (c *Client) CreateTask(ctx context.Context, callbackID int, command, params string) (*Task, error) {
 	req := graphql.NewRequest(CreateTask)
-	
+
 	req.Var("callback_id", callbackID)
 	req.Var("command", command)
 	req.Var("params", params)
 	req.Var("tasking_location", "command_line")
 	req.Header.Set("apitoken", c.token)
-	
+
 	var resp struct {
 		CreateTask struct {
 			Status    string `json:"status"`
@@ -236,68 +236,68 @@ func (c *Client) CreateTask(ctx context.Context, callbackID int, command, params
 			Error     string `json:"error"`
 		} `json:"createTask"`
 	}
-	
+
 	if err := c.client.Run(ctx, req, &resp); err != nil {
 		return nil, fmt.Errorf("failed to create task: %w", err)
 	}
-	
+
 	if resp.CreateTask.Status != "success" {
 		return nil, fmt.Errorf("task creation failed: %s", resp.CreateTask.Error)
 	}
-	
+
 	return &Task{
-		ID:        resp.CreateTask.ID,
-		DisplayID: resp.CreateTask.DisplayID,
-		Command:   command,
-		Params:    params,
-		Status:    "submitted",
+		ID:         resp.CreateTask.ID,
+		DisplayID:  resp.CreateTask.DisplayID,
+		Command:    command,
+		Params:     params,
+		Status:     "submitted",
 		CallbackID: callbackID,
 	}, nil
 }
 
 func (c *Client) GetTaskResponse(ctx context.Context, taskID int) (*Task, error) {
 	req := graphql.NewRequest(GetTask)
-	
+
 	req.Var("id", taskID)
 	req.Header.Set("apitoken", c.token)
-	
+
 	var resp struct {
 		Task struct {
-			ID            int    `json:"id"`
-			DisplayID     int    `json:"display_id"`
-			CommandName   string `json:"command_name"`
+			ID             int    `json:"id"`
+			DisplayID      int    `json:"display_id"`
+			CommandName    string `json:"command_name"`
 			OriginalParams string `json:"original_params"`
 			DisplayParams  string `json:"display_params"`
-			Status        string `json:"status"`
-			Completed     bool   `json:"completed"`
-			Callback      struct {
+			Status         string `json:"status"`
+			Completed      bool   `json:"completed"`
+			Callback       struct {
 				ID        int `json:"id"`
 				DisplayID int `json:"display_id"`
 			} `json:"callback"`
 		} `json:"task_by_pk"`
 	}
-	
+
 	if err := c.client.Run(ctx, req, &resp); err != nil {
 		return nil, fmt.Errorf("failed to get task: %w", err)
 	}
-	
+
 	// Get task responses
 	responseReq := graphql.NewRequest(GetTaskResponses)
-	
+
 	responseReq.Var("task_display_id", resp.Task.DisplayID)
 	responseReq.Header.Set("apitoken", c.token)
-	
+
 	var responseResp struct {
 		Response []struct {
 			ResponseText string `json:"response_text"`
 			Timestamp    string `json:"timestamp"`
 		} `json:"response"`
 	}
-	
+
 	if err := c.client.Run(ctx, responseReq, &responseResp); err != nil {
 		return nil, fmt.Errorf("failed to get task response: %w", err)
 	}
-	
+
 	// Concatenate all response chunks in chronological order
 	var responseBuilder strings.Builder
 	for _, resp := range responseResp.Response {
@@ -305,12 +305,12 @@ func (c *Client) GetTaskResponse(ctx context.Context, taskID int) (*Task, error)
 		responseBuilder.WriteString(decodedText)
 	}
 	response := responseBuilder.String()
-	
+
 	status := resp.Task.Status
 	if resp.Task.Completed {
 		status = "completed"
 	}
-	
+
 	return &Task{
 		ID:         resp.Task.ID,
 		DisplayID:  resp.Task.DisplayID,
@@ -399,15 +399,15 @@ func (c *Client) GetCallbackTasks(ctx context.Context, callbackID int) ([]Task,
 
 	var resp struct {
 		Task []struct {
-			ID            int    `json:"id"`
-			DisplayID     int    `json:"display_id"`
-			CommandName   string `json:"command_name"`
+			ID             int    `json:"id"`
+			DisplayID      int    `json:"display_id"`
+			CommandName    string `json:"command_name"`
 			OriginalParams string `json:"original_params"`
 			DisplayParams  string `json:"display_params"`
-			Status        string `json:"status"`
-			Completed     bool   `json:"completed"`
-			Timestamp     string `json:"timestamp"`
-			Callback      struct {
+			Status         string `json:"status"`
+			Completed      bool   `json:"completed"`
+			Timestamp      string `json:"timestamp"`
+			Callback       struct {
 				ID        int `json:"id"`
 				DisplayID int `json:"display_id"`
 			} `json:"callback"`
@@ -615,15 +615,15 @@ func (c *Client) GetTasksWithResponses(ctx context.Context, callbackID int, limi
 
 	var resp struct {
 		Task []struct {
-			ID            int    `json:"id"`
-			DisplayID     int    `json:"display_id"`
-			CommandName   string `json:"command_name"`
+			ID             int    `json:"id"`
+			DisplayID      int    `json:"display_id"`
+			CommandName    string `json:"command_name"`
 			OriginalParams string `json:"original_params"`
 			DisplayParams  string `json:"display_params"`
-			Status        string `json:"status"`
-			Completed     bool   `json:"completed"`
-			Timestamp     string `json:"timestamp"`
-			Callback      struct {
+			Status         string `json:"status"`
+			Completed      bool   `json:"completed"`
+			Timestamp      string `json:"timestamp"`
+			Callback       struct {
 				ID        int    `json:"id"`
 				DisplayID int    `json:"display_id"`
 				Host      string `json:"host"`
@@ -681,15 +681,15 @@ func (c *Client) GetAllTasks(ctx context.Context, limit int) ([]Task, error) {
 
 	var resp struct {
 		Task []struct {
-			ID            int    `json:"id"`
-			DisplayID     int    `json:"display_id"`
-			CommandName   string `json:"command_name"`
+			ID             int    `json:"id"`
+			DisplayID      int    `json:"display_id"`
+			CommandName    string `json:"command_name"`
 			OriginalParams string `json:"original_params"`
 			DisplayParams  string `json:"display_params"`
-			Status        string `json:"status"`
-			Completed     bool   `json:"completed"`
-			Timestamp     string `json:"timestamp"`
-			Callback      struct {
+			Status         string `json:"status"`
+			Completed      bool   `json:"completed"`
+			Timestamp      string `json:"timestamp"`
+			Callback       struct {
 				ID        int    `json:"id"`
 				DisplayID int    `json:"display_id"`
 				Host      string `json:"host"`
@@ -737,15 +737,15 @@ func (c *Client) GetAllTasksWithResponses(ctx context.Context, limit int) ([]Tas
 
 	var resp struct {
 		Task []struct {
-			ID            int    `json:"id"`
-			DisplayID     int    `json:"display_id"`
-			CommandName   string `json:"command_name"`
+			ID             int    `json:"id"`
+			DisplayID      int    `json:"display_id"`
+			CommandName    string `json:"command_name"`
 			OriginalParams string `json:"original_params"`
 			DisplayParams  string `json:"display_params"`
-			Status        string `json:"status"`
-			Completed     bool   `json:"completed"`
-			Timestamp     string `json:"timestamp"`
-			Callback      struct {
+			Status         string `json:"status"`
+			Completed      bool   `json:"completed"`
+			Timestamp      string `json:"timestamp"`
+			Callback       struct {
 				ID        int    `json:"id"`
 				DisplayID int    `json:"display_id"`
 				Host      string `json:"host"`
@@ -869,4 +869,4 @@ func (c *Client) GetPayloads(ctx context.Context) ([]Payload, error) {
 	}
 
 	return payloads, nil
-}
\ No newline at end of file
+}
pkg/mythic/client_test.go
@@ -19,7 +19,7 @@ func TestIsBase64(t *testing.T) {
 		{
 			name:     "valid base64 text that decodes to text",
 			input:    "SGVsbG8gV29ybGQ=", // "Hello World" in base64
-			expected: true, // Actually returns true because the original is longer than decoded
+			expected: true,               // Actually returns true because the original is longer than decoded
 		},
 		{
 			name:     "short string",
@@ -39,7 +39,7 @@ func TestIsBase64(t *testing.T) {
 		{
 			name:     "valid base64 but short",
 			input:    "dGVzdA==", // "test" in base64
-			expected: true, // Actually returns true because original is longer than decoded
+			expected: true,       // Actually returns true because original is longer than decoded
 		},
 	}
 
@@ -156,4 +156,4 @@ func TestClientMethodsExist(t *testing.T) {
 	if err == nil {
 		t.Error("Expected error due to canceled context")
 	}
-}
\ No newline at end of file
+}
pkg/mythic/queries.go
@@ -616,4 +616,4 @@ query GetAllTasksWithResponsesFromAllCallbacks($limit: Int) {
             timestamp
         }
     }
-}`
\ No newline at end of file
+}`
main.go
@@ -4,4 +4,4 @@ import "mysh/cmd"
 
 func main() {
 	cmd.Execute()
-}
\ No newline at end of file
+}
README.md
@@ -107,6 +107,13 @@ mysh interact 1
 
 ## Project Structure
 
+### contrib Directory
+The `contrib/` directory contains checkouts of related Mythic repositories for reference during development:
+- `contrib/Mythic/` - Main Mythic server source code
+- `contrib/Mythic_Scripting/` - Python scripting library for Mythic
+- Located in this repository for easy reference when implementing GraphQL queries and mutations
+- Check `contrib/Mythic/hasura-docker/metadata/metadata/actions.graphql` for available GraphQL operations
+
 ### GraphQL Queries Synchronization
 The project maintains a 1:1 copy of GraphQL queries from the Python Mythic_Scripting library:
 - **Source:** `contrib/Mythic_Scripting/mythic/graphql_queries.py`
TODO.md
@@ -1,15 +1,11 @@
 
 - grep --delete - flag that deletes the tasking from the server that match the grep - require confirmation
-
-
 - forge payloads - equivalency with execute_assembly and inline_assembly
+
 - MYTHIC_API_INSECURE= boolean --insecure flag - and invert default = false
 - update output table formats to respect terminal width
 - invert cobra-cli nto functions (no global vars)
 
-
-
-
 - โœ… grep --raw - only diplay of all matching items raw output follow grep -R style single-line file dilimeters in the output
 - โœ… use per-server cache dirs
 - โœ… make sure raw output has a newline at the end