| 398 | } |
| 399 | |
| 400 | func marshalUIGetIssueFields(fields []IssueField) (*mcp.CallToolResult, any, error) { |
| 401 | resultFields := make([]map[string]any, 0, len(fields)) |
| 402 | for _, field := range fields { |
| 403 | if !uiSupportedIssueFieldDataType(field.DataType) { |
| 404 | continue |
| 405 | } |
| 406 | |
| 407 | fieldResult := map[string]any{ |
| 408 | "id": field.ID, |
| 409 | "name": field.Name, |
| 410 | "data_type": field.DataType, |
| 411 | "description": field.Description, |
| 412 | } |
| 413 | |
| 414 | if field.DataType == "single_select" { |
| 415 | fieldOptions := append([]IssueSingleSelectFieldOption(nil), field.Options...) |
| 416 | sort.SliceStable(fieldOptions, func(i, j int) bool { |
| 417 | left, leftOK := issueFieldOptionPriority(fieldOptions[i]) |
| 418 | right, rightOK := issueFieldOptionPriority(fieldOptions[j]) |
| 419 | if leftOK != rightOK { |
| 420 | return leftOK |
| 421 | } |
| 422 | return left < right |
| 423 | }) |
| 424 | |
| 425 | options := make([]map[string]string, 0, len(fieldOptions)) |
| 426 | for _, option := range fieldOptions { |
| 427 | options = append(options, map[string]string{ |
| 428 | "name": option.Name, |
| 429 | "description": option.Description, |
| 430 | "color": option.Color, |
| 431 | }) |
| 432 | } |
| 433 | fieldResult["options"] = options |
| 434 | } |
| 435 | |
| 436 | resultFields = append(resultFields, fieldResult) |
| 437 | } |
| 438 | |
| 439 | r, err := json.Marshal(map[string]any{ |
| 440 | "fields": resultFields, |
| 441 | "totalCount": len(resultFields), |
| 442 | }) |
| 443 | if err != nil { |
| 444 | return utils.NewToolResultErrorFromErr("failed to marshal issue fields", err), nil, nil |
| 445 | } |
| 446 | |
| 447 | return utils.NewToolResultText(string(r)), nil, nil |
| 448 | } |
| 449 | |
| 450 | func uiSupportedIssueFieldDataType(dataType string) bool { |
| 451 | switch dataType { |