Skip to content

Commit 4e7e2a5

Browse files
committed
Resolve project view fields by name
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: c6f8ede6-efee-4191-900d-59a1bb0af000
1 parent b5eb2a7 commit 4e7e2a5

5 files changed

Lines changed: 279 additions & 26 deletions

File tree

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1141,7 +1141,8 @@ The following sets of tools are available:
11411141
- `title`: The project title. Required for 'create_project' method. (string, optional)
11421142
- `updated_field`: The field/value to apply, using {"id": 123, "value": ...} or {"name": "Status", "value": ...}; null clears the field. Required for 'update_project_item' and 'update_project_items', where one top-level field/value applies to every item in a batch. For 'update_project_item' SINGLE_SELECT fields, the name form accepts option names; the ID form expects an option ID. (object, optional)
11431143
- `view_id`: Project view node ID for update or delete; must belong to owner/project_number. (string, optional)
1144-
- `visible_fields`: Field database IDs for table or board creation; unsupported for roadmap. (string[], optional)
1144+
- `visible_field_names`: Field names for table or board creation; mutually exclusive with visible_fields. (string[], optional)
1145+
- `visible_fields`: Field database IDs for table or board creation; mutually exclusive with visible_field_names. (string[], optional)
11451146

11461147
</details>
11471148

pkg/github/__toolsnaps__/projects_write.snap

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,8 +249,15 @@
249249
"description": "Project view node ID for update or delete; must belong to owner/project_number.",
250250
"type": "string"
251251
},
252+
"visible_field_names": {
253+
"description": "Field names for table or board creation; mutually exclusive with visible_fields.",
254+
"items": {
255+
"type": "string"
256+
},
257+
"type": "array"
258+
},
252259
"visible_fields": {
253-
"description": "Field database IDs for table or board creation; unsupported for roadmap.",
260+
"description": "Field database IDs for table or board creation; mutually exclusive with visible_field_names.",
254261
"items": {
255262
"type": "string"
256263
},

pkg/github/projects.go

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -757,7 +757,14 @@ func ProjectsWrite(t translations.TranslationHelperFunc) inventory.ServerTool {
757757
},
758758
"visible_fields": {
759759
Type: "array",
760-
Description: "Field database IDs for table or board creation; unsupported for roadmap.",
760+
Description: "Field database IDs for table or board creation; mutually exclusive with visible_field_names.",
761+
Items: &jsonschema.Schema{
762+
Type: "string",
763+
},
764+
},
765+
"visible_field_names": {
766+
Type: "array",
767+
Description: "Field names for table or board creation; mutually exclusive with visible_fields.",
761768
Items: &jsonschema.Schema{
762769
Type: "string",
763770
},
@@ -862,13 +869,12 @@ func ProjectsWrite(t translations.TranslationHelperFunc) inventory.ServerTool {
862869
return utils.NewToolResultError(err.Error()), nil, nil
863870
}
864871

865-
gqlClient, err := deps.GetGQLClient(ctx)
866-
if err != nil {
867-
return utils.NewToolResultError(err.Error()), nil, nil
868-
}
869-
870872
// create_project does not require project_number or a REST client
871873
if method == projectsMethodCreateProject {
874+
gqlClient, gqlErr := deps.GetGQLClient(ctx)
875+
if gqlErr != nil {
876+
return utils.NewToolResultError(gqlErr.Error()), nil, nil
877+
}
872878
return createProject(ctx, gqlClient, owner, ownerType, args)
873879
}
874880

@@ -890,6 +896,26 @@ func ProjectsWrite(t translations.TranslationHelperFunc) inventory.ServerTool {
890896
}
891897
}
892898

899+
if method == projectsMethodCreateProjectView {
900+
visibleFieldNames, namesErr := OptionalStringArrayParam(args, "visible_field_names")
901+
if namesErr != nil {
902+
return utils.NewToolResultError(namesErr.Error()), nil, nil
903+
}
904+
var gqlClient *githubv4.Client
905+
if len(visibleFieldNames) > 0 {
906+
gqlClient, err = deps.GetGQLClient(ctx)
907+
if err != nil {
908+
return utils.NewToolResultError(err.Error()), nil, nil
909+
}
910+
}
911+
return createProjectView(ctx, client, gqlClient, args, owner, ownerType, projectNumber, visibleFieldNames)
912+
}
913+
914+
gqlClient, err := deps.GetGQLClient(ctx)
915+
if err != nil {
916+
return utils.NewToolResultError(err.Error()), nil, nil
917+
}
918+
893919
switch method {
894920
case projectsMethodAddProjectItem:
895921
itemType, err := RequiredParam[string](args, "item_type")
@@ -980,8 +1006,6 @@ func ProjectsWrite(t translations.TranslationHelperFunc) inventory.ServerTool {
9801006
return createProjectStatusUpdate(ctx, gqlClient, owner, ownerType, projectNumber, body, status, startDate, targetDate)
9811007
case projectsMethodCreateIterationField:
9821008
return createIterationField(ctx, gqlClient, owner, ownerType, projectNumber, args)
983-
case projectsMethodCreateProjectView:
984-
return createProjectView(ctx, client, args, owner, ownerType, projectNumber)
9851009
case projectsMethodUpdateProjectView:
9861010
return updateProjectView(ctx, gqlClient, args, owner, ownerType, projectNumber)
9871011
case projectsMethodDeleteProjectView:
@@ -1891,7 +1915,7 @@ func getProjectView(ctx context.Context, gqlClient *githubv4.Client, viewID stri
18911915
return utils.NewToolResultText(string(result)), !bool(query.Node.ProjectView.Project.Public), nil, nil
18921916
}
18931917

1894-
func createProjectView(ctx context.Context, client *github.Client, args map[string]any, owner, ownerType string, projectNumber int) (*mcp.CallToolResult, any, error) {
1918+
func createProjectView(ctx context.Context, client *github.Client, gqlClient *githubv4.Client, args map[string]any, owner, ownerType string, projectNumber int, visibleFieldNames []string) (*mcp.CallToolResult, any, error) {
18951919
name, err := RequiredParam[string](args, "name")
18961920
if err != nil {
18971921
return utils.NewToolResultError(err.Error()), nil, nil
@@ -1915,8 +1939,22 @@ func createProjectView(ctx context.Context, client *github.Client, args map[stri
19151939
if err != nil {
19161940
return utils.NewToolResultError(err.Error()), nil, nil
19171941
}
1942+
if len(visibleFields) > 0 && len(visibleFieldNames) > 0 {
1943+
return utils.NewToolResultError("provide either 'visible_fields' or 'visible_field_names', not both"), nil, nil
1944+
}
1945+
if len(visibleFieldNames) > 0 {
1946+
resolvedIDs, resolveErr := resolveFieldNamesToIDs(ctx, gqlClient, owner, ownerType, projectNumber, visibleFieldNames)
1947+
if resolveErr != nil {
1948+
var structured *ghErrors.StructuredResolutionError
1949+
if errors.As(resolveErr, &structured) {
1950+
return ghErrors.NewStructuredResolutionErrorResponse(structured), nil, nil
1951+
}
1952+
return utils.NewToolResultError(resolveErr.Error()), nil, nil
1953+
}
1954+
visibleFields = resolvedIDs
1955+
}
19181956
if layout == githubv4.ProjectV2ViewLayoutRoadmapLayout && len(visibleFields) > 0 {
1919-
return utils.NewToolResultError("visible_fields is not supported for roadmap views"), nil, nil
1957+
return utils.NewToolResultError("visible fields are not supported for roadmap views"), nil, nil
19201958
}
19211959

19221960
requestBody := CreateProjectV2ViewRequest{

pkg/github/projects_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -888,6 +888,7 @@ func Test_ProjectsWrite(t *testing.T) {
888888
assert.Contains(t, inputSchema.Properties, "layout")
889889
assert.Contains(t, inputSchema.Properties, "filter")
890890
assert.Contains(t, inputSchema.Properties, "visible_fields")
891+
assert.Contains(t, inputSchema.Properties, "visible_field_names")
891892
assert.Contains(t, inputSchema.Properties["method"].Enum, projectsMethodCreateProjectView)
892893
assert.Contains(t, inputSchema.Properties["method"].Enum, projectsMethodUpdateProjectView)
893894
assert.Contains(t, inputSchema.Properties["method"].Enum, projectsMethodDeleteProjectView)

0 commit comments

Comments
 (0)