Some notes on how to read GitHub notifications from the gh CLI.
The following are the notes I wrote in a GitHub issue for accessing GitHub notifications from the CLI, including formatting them to have clickable links/etc:
This could be potentially improved further if these issues get resolved positively:
- cli/cli#10261
-
Allow
--jqand--templateto be used together ingh api
-
- cli/cli#10262
-
Add custom formatting functions to
--jqsimilar to those added to--template
-
- cli/cli#10263
-
Allow passing additional arguments through to
--jqscript, just like we can withjq --arg
-
I also added a zsh wrapper script version of this to my dotfiles:
Which I then aliased as gh notifications:
Here are my original notes, and the resulting gh api command:
The ideal version would include
- usernames involved in the update (have to switch the query to GraphQL)
- the correct web url to click on - needs mangling of API url or url construction from parts for issues, PRs and other objects
- Handle non repo updates like from projects etc
- Show the status of the issue(open / closed) / PR(draft,closed, merged, open) color coded like the UI does.
- Group by repository not just sort by date.
Originally posted by @manquer in #659
Since
gh apidoesn't allow us to pass both--jqand--templatecurrently:And because the Go template language doesn't seem to allow us to perform more complex manipulations:
We can seemly manipulate the output from
ghwith either the--jqor--templateflags:Templates are go templates:
Which according to ChatGPT, doesn't seem to allow more complex string manipulations:
Using Go's
text/templateorhtml/templatepackage, you cannot directly perform complex string manipulations like regex or advanced parsing, as the templates focus on simple variable interpolation and basic functions (e.g.,split,join,index).Originally posted by @0xdevalias in #4
We first need to convert the original
--templatecommand to an equivalent using only--jq:We could do this using
jq's@tsv+ the externalcolumnprogram like this:gh api notifications \ --method GET \ -F participating=true \ --jq ' def timeago: . | fromdateiso8601 | now - . | . / 60 | floor | # Convert to minutes if . < 60 then (. | tostring + " minutes ago") elif . < 1440 then (. / 60 | floor | tostring + " hours ago") elif . < 43200 then (. / 1440 | floor | tostring + " days ago") elif . < 525600 then (. / 43200 | floor | tostring + " months ago") else (. / 525600 | floor | tostring + " years ago") end; .[] | [ .repository.full_name, (.subject.title | .[:100]), .subject.type, .reason, (.updated_at | timeago) ] | @tsv' \ --paginate | column -t -s $'\t'But if we wanted to fully encapsulate the processing within
--jq, we could create an extraljustfunction and use it like this:gh api notifications \ --method GET \ -F participating=true \ --jq ' def timeago: . | fromdateiso8601 | now - . | . / 60 | floor | # Convert to minutes if . < 60 then (. | tostring + " minutes ago") elif . < 1440 then (. / 60 | floor | tostring + " hours ago") elif . < 43200 then (. / 1440 | floor | tostring + " days ago") elif . < 525600 then (. / 43200 | floor | tostring + " months ago") else (. / 525600 | floor | tostring + " years ago") end; def ljust(width): . + " " * (width - (. | length)); .[] | [ (.repository.full_name | ljust(25)), (.subject.title | .[:50] | ljust(50)), (.subject.type | ljust(12)), (.reason | ljust(8)), (.updated_at | timeago) ] | join(" ")' \ --paginateBoth of these give output similar to the original:
Original
--template:prisma/prisma Support for a Union type Issue manual 45 minutes ago jekyll/jekyll Rename `baseurl` to `base_path` Issue manual 3 months ago
--jq+column:prisma/prisma Support for a Union type Issue manual 43 minutes ago jekyll/jekyll Rename `baseurl` to `base_path` Issue manual 3 months agoOnly
--jqprisma/prisma Support for a Union type Issue manual 43 minutes ago jekyll/jekyll Rename `baseurl` to `base_path` Issue manual 3 months agoNow that the logic is all within
--jq, we can define extra functions to manipulate and improve the output based on the additional requirements/desires.For example (not 100% thoroughly tested, may be bugs), the following adds conversions for the
web_url, displying the status, and depending which format block you uncomment, grouping by repo:gh api notifications \ --method GET \ -F participating=true \ --jq ' def timeago: . | fromdateiso8601 | now - . | . / 60 | floor | if . < 60 then (. | tostring + " minutes ago") elif . < 1440 then (. / 60 | floor | tostring + " hours ago") elif . < 43200 then (. / 1440 | floor | tostring + " days ago") elif . < 525600 then (. / 43200 | floor | tostring + " months ago") else (. / 525600 | floor | tostring + " years ago") end; def ljust(width): . + " " * (width - (. | length)); def api_to_web_url: if test("^https://api.github.com/repos/[^/]+/[^/]+/(issues|pulls)/[0-9]+$") then sub("^https://api.github.com/repos/"; "https://github.com/") elif test("^https://api.github.com/repos/[^/]+/[^/]+/issues/comments/[0-9]+$") then capture("^https://api.github.com/repos/(?<repo>[^/]+/[^/]+)/issues/comments/(?<comment>[0-9]+)$") | "https://github.com/\(.repo)/issues#issuecomment-\(.comment)" elif test("^https://api.github.com/repos/") then sub("^https://api.github.com/repos/"; "https://github.com/") else . end; def get_status: if .subject.type == "Issue" then if .state == "closed" then "🔴 Closed" else "🟢 Open" end elif .subject.type == "PullRequest" then if .state == "merged" then "🟣 Merged" elif .state == "closed" then "🔴 Closed" elif .draft then "⚪ Draft" else "🟢 Open" end else " -" end; def format_item: [ (.repository.full_name | ljust(25)), (.subject.title | .[:50] | ljust(50)), (.subject.type | ljust(12)), (get_status | ljust(12)), (.reason | ljust(8)), (.updated_at | timeago | ljust(15)), (.subject.url | api_to_web_url) ] | join(" "); def format_grouped_item: [ " ", # Indent for grouping (.subject.title | .[:50] | ljust(50)), (.subject.type | ljust(12)), (get_status | ljust(12)), (.reason | ljust(8)), (.updated_at | timeago | ljust(15)), (.subject.url | api_to_web_url) ] | join(" "); def format_repo_header: .repository.html_url | sub("^https://github.com/"; "") | "\n\u001b[1m\u001b[36m=== \(.) ===\u001b[0m"; # GROUPING SWITCH: Comment out one of these two blocks # Block 1: No grouping - just format and output .[] | format_item # Block 2: With grouping #group_by(.repository.full_name) | #map({ # group: ., # max_time: ([.[].updated_at | fromdateiso8601] | max) #}) | #sort_by(-.max_time) | #.[].group | #(.[0] | format_repo_header) as $header | #($header, (.[] | format_grouped_item))' \ --paginateWhich gives output like this for non-grouped:
ggerganov/whisper.cpp MacWhisper, native macOS app for Whisper Discussion - manual 6 minutes ago https://github.com/ggerganov/whisper.cpp/discussions/420 prisma/prisma Support for a Union type Issue 🟢 Open manual 1 hours ago https://github.com/prisma/prisma/issues/2505 jekyll/jekyll Rename `baseurl` to `base_path` Issue 🟢 Open manual 3 months ago https://github.com/jekyll/jekyll/issues/4711And this for grouped:
=== ggerganov/whisper.cpp === MacWhisper, native macOS app for Whisper Discussion - manual 7 minutes ago https://github.com/ggerganov/whisper.cpp/discussions/420 === prisma/prisma === Support for a Union type Issue 🟢 Open manual 1 hours ago https://github.com/prisma/prisma/issues/2505 === jekyll/jekyll === Rename `baseurl` to `base_path` Issue 🟢 Open manual 3 months ago https://github.com/jekyll/jekyll/issues/4711This could be potentially improved further if either of these issues get resolved positively:
Originally posted by @0xdevalias in cli/cli#659 (comment)
Seems like the Mobile app is using some graphQL API endpoints behind a feature flag
Interesting.. willing to share the details for them? That way we might just be able to use them directly in a
ghextension to add support for it?
POST /graphql HTTP/2
Host: api.github.com
Content-Type: application/json
Graphql-Features: merge_queue,private_profile_setting,project_next_field_configuration,issues_close_state,project_next_recent_connection,file_level_commenting,issue_types,sub_issues
Accept: application/vnd.github.merge-info-preview+json,application/vnd.github.shadow-cat-preview+json,application/vnd.github.echo-preview+json,application/vnd.github.starfox-preview+json,application/vnd.github.doctor-strange-preview+json
Apollographql-Client-Version: 1.192.0-152022212
Authorization: Bearer REDACTED
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB;q=1.0, en-AU;q=0.9, ja-AU;q=0.8, fa-AU;q=0.7
Content-Length: 4030
User-Agent: GitHub/1.192.0 (com.github.stormbreaker.prod; build:152022212; iOS 18.2.1; iPhone15,3)
X-Apollo-Operation-Type: query
Apollographql-Client-Name: com.github.stormbreaker.prod-apollo-ios
X-Apollo-Operation-Name: Inbox
{
"operationName": "Inbox",
"query": "query Inbox($first: Int!, $after: String, $filterBy: NotificationThreadFilters, $query: String, $avatarSize: Int!) { viewer { __typename id ...WebNotificationsEnabledFragment notificationThreads( first: $first after: $after filterBy: $filterBy query: $query ) { __typename pageInfo { __typename hasNextPage endCursor } totalCount nodes { __typename ...NotificationThreadCommonFieldsFragment url subject { __typename ... on CheckSuite { ...InboxSubjectCheckSuiteFieldsFragment } ... on WorkflowRun { ...InboxSubjectWorkflowRunFieldsFragment } ... on Commit { ...InboxSubjectCommitFieldsFragment } ... on Gist { ...InboxSubjectGistFieldsFragment } ... on TeamDiscussion { ...InboxSubjectTeamDiscussionFieldsFragment } ... on Issue { ...InboxSubjectIssueFieldsFragment } ... on PullRequest { ...InboxSubjectPullRequestFieldsFragment } ... on Release { ...InboxSubjectReleaseFieldsFragment } ... on RepositoryVulnerabilityAlert { ...InboxSubjectRepositoryVulnerabilityAlertFieldsFragment } ... on RepositoryAdvisory { ...InboxSubjectRepositoryAdvisoryFieldsFragment } ...InboxSubjectDiscussionFieldsFragment ... on RepositoryDependabotAlertsThread { ...InboxSubjectRepositoryDependabotAlertsThreadFieldsFragment } ... on SecurityAdvisory { ...InboxSubjectSecurityAdvisoryFieldsFragment } } } } } }\nfragment AvatarFragment on Actor { __typename avatarUrl(size: $avatarSize) }\nfragment InboxSubjectCheckSuiteFieldsFragment on CheckSuite { __typename id url conclusion status }\nfragment InboxSubjectCommitFieldsFragment on Commit { __typename id abbreviatedOid url repository { __typename id owner { __typename id login } name } }\nfragment InboxSubjectDiscussionFieldsFragment on Discussion { __typename id url number discussionStateReason: stateReason answer { __typename id } category { __typename id isAnswerable } repository { __typename id isOrganizationDiscussionRepository } }\nfragment InboxSubjectGistFieldsFragment on Gist { __typename url id }\nfragment InboxSubjectIssueFieldsFragment on Issue { __typename id number issueState: state stateReason issueHtmlTitle: titleHTML url }\nfragment InboxSubjectPullRequestFieldsFragment on PullRequest { __typename id number pullRequestHtmlTitle: titleHTML url ...PullRequestStateIcon }\nfragment InboxSubjectReleaseFieldsFragment on Release { __typename id tagName url }\nfragment InboxSubjectRepositoryAdvisoryFieldsFragment on RepositoryAdvisory { __typename id url }\nfragment InboxSubjectRepositoryDependabotAlertsThreadFieldsFragment on RepositoryDependabotAlertsThread { __typename id notificationsPermalink }\nfragment InboxSubjectRepositoryVulnerabilityAlertFieldsFragment on RepositoryVulnerabilityAlert { __typename id permalink }\nfragment InboxSubjectSecurityAdvisoryFieldsFragment on SecurityAdvisory { __typename id ghsaId notificationsPermalink }\nfragment InboxSubjectTeamDiscussionFieldsFragment on TeamDiscussion { __typename url id }\nfragment InboxSubjectWorkflowRunFieldsFragment on WorkflowRun { __typename id url runNumber workflow { __typename id name } checkSuite { __typename id } }\nfragment ListSubscribableFragment on Subscribable { __typename id viewerSubscription viewerCanSubscribe }\nfragment NotificationThreadCommonFieldsFragment on NotificationThread { __typename id threadType title isUnread unreadItemsCount lastUpdatedAt subscriptionStatus summaryItemAuthor { __typename id ...AvatarFragment } summaryItemBody isArchived isSaved reason list { __typename ...ListSubscribableFragment ... on Repository { id owner { __typename id login } name } ... on User { id login userName: name } ... on Team { id organization { __typename id login } slug } ... on Organization { id login } } }\nfragment PullRequestStateIcon on PullRequest { __typename pullRequestState: state isDraft mergeQueueEntry { __typename id position } }\nfragment WebNotificationsEnabledFragment on User { __typename notificationSettings { __typename getsParticipatingWeb getsWatchingWeb } }",
"variables":
{
"avatarSize": 48,
"first": 30,
"query": ""
}
}query Inbox(
$first: Int!
$after: String
$filterBy: NotificationThreadFilters
$query: String
$avatarSize: Int!
) {
viewer {
__typename
id
...WebNotificationsEnabledFragment
notificationThreads(
first: $first
after: $after
filterBy: $filterBy
query: $query
) {
__typename
pageInfo {
__typename
hasNextPage
endCursor
}
totalCount
nodes {
__typename
...NotificationThreadCommonFieldsFragment
url
subject {
__typename
... on CheckSuite {
...InboxSubjectCheckSuiteFieldsFragment
}
... on WorkflowRun {
...InboxSubjectWorkflowRunFieldsFragment
}
... on Commit {
...InboxSubjectCommitFieldsFragment
}
... on Gist {
...InboxSubjectGistFieldsFragment
}
... on TeamDiscussion {
...InboxSubjectTeamDiscussionFieldsFragment
}
... on Issue {
...InboxSubjectIssueFieldsFragment
}
... on PullRequest {
...InboxSubjectPullRequestFieldsFragment
}
... on Release {
...InboxSubjectReleaseFieldsFragment
}
... on RepositoryVulnerabilityAlert {
...InboxSubjectRepositoryVulnerabilityAlertFieldsFragment
}
... on RepositoryAdvisory {
...InboxSubjectRepositoryAdvisoryFieldsFragment
}
...InboxSubjectDiscussionFieldsFragment
... on RepositoryDependabotAlertsThread {
...InboxSubjectRepositoryDependabotAlertsThreadFieldsFragment
}
... on SecurityAdvisory {
...InboxSubjectSecurityAdvisoryFieldsFragment
}
}
}
}
}
}
fragment AvatarFragment on Actor {
__typename
avatarUrl(size: $avatarSize)
}
fragment InboxSubjectCheckSuiteFieldsFragment on CheckSuite {
__typename
id
url
conclusion
status
}
fragment InboxSubjectCommitFieldsFragment on Commit {
__typename
id
abbreviatedOid
url
repository {
__typename
id
owner {
__typename
id
login
}
name
}
}
fragment InboxSubjectDiscussionFieldsFragment on Discussion {
__typename
id
url
number
discussionStateReason: stateReason
answer {
__typename
id
}
category {
__typename
id
isAnswerable
}
repository {
__typename
id
isOrganizationDiscussionRepository
}
}
fragment InboxSubjectGistFieldsFragment on Gist {
__typename
url
id
}
fragment InboxSubjectIssueFieldsFragment on Issue {
__typename
id
number
issueState: state
stateReason
issueHtmlTitle: titleHTML
url
}
fragment InboxSubjectPullRequestFieldsFragment on PullRequest {
__typename
id
number
pullRequestHtmlTitle: titleHTML
url
...PullRequestStateIcon
}
fragment InboxSubjectReleaseFieldsFragment on Release {
__typename
id
tagName
url
}
fragment InboxSubjectRepositoryAdvisoryFieldsFragment on RepositoryAdvisory {
__typename
id
url
}
fragment InboxSubjectRepositoryDependabotAlertsThreadFieldsFragment on RepositoryDependabotAlertsThread {
__typename
id
notificationsPermalink
}
fragment InboxSubjectRepositoryVulnerabilityAlertFieldsFragment on RepositoryVulnerabilityAlert {
__typename
id
permalink
}
fragment InboxSubjectSecurityAdvisoryFieldsFragment on SecurityAdvisory {
__typename
id
ghsaId
notificationsPermalink
}
fragment InboxSubjectTeamDiscussionFieldsFragment on TeamDiscussion {
__typename
url
id
}
fragment InboxSubjectWorkflowRunFieldsFragment on WorkflowRun {
__typename
id
url
runNumber
workflow {
__typename
id
name
}
checkSuite {
__typename
id
}
}
fragment ListSubscribableFragment on Subscribable {
__typename
id
viewerSubscription
viewerCanSubscribe
}
fragment NotificationThreadCommonFieldsFragment on NotificationThread {
__typename
id
threadType
title
isUnread
unreadItemsCount
lastUpdatedAt
subscriptionStatus
summaryItemAuthor {
__typename
id
...AvatarFragment
}
summaryItemBody
isArchived
isSaved
reason
list {
__typename
...ListSubscribableFragment
... on Repository {
id
owner {
__typename
id
login
}
name
}
... on User {
id
login
userName: name
}
... on Team {
id
organization {
__typename
id
login
}
slug
}
... on Organization {
id
login
}
}
}
fragment PullRequestStateIcon on PullRequest {
__typename
pullRequestState: state
isDraft
mergeQueueEntry {
__typename
id
position
}
}
fragment WebNotificationsEnabledFragment on User {
__typename
notificationSettings {
__typename
getsParticipatingWeb
getsWatchingWeb
}
}- https://github.com/cli/cli/blob/fe74349fe460cd80c21116eabd2753c0ba746f63/pkg/cmd/api/api.go#L277-L277
- https://github.com/cli/cli/blob/fe74349fe460cd80c21116eabd2753c0ba746f63/pkg/cmd/api/api.go#L683-L689
- https://github.com/cli/cli/blob/fe74349fe460cd80c21116eabd2753c0ba746f63/api/client.go#L17-L24
- https://github.com/cli/cli/blob/fe74349fe460cd80c21116eabd2753c0ba746f63/api/client.go#L54-L64
gh api graphql \
--header 'Graphql-Features: merge_queue,private_profile_setting,project_next_field_configuration,issues_close_state,project_next_recent_connection,file_level_commenting,issue_types,sub_issues' \
--preview 'merge-info' \
--preview 'shadow-cat' \
--preview 'echo' \
--preview 'starfox' \
--preview 'doctor-strange' \
-F avatarSize='48' \
-F first='30' \
-F searchQuery='' \
-F operationName='Inbox' \
--raw-field query='
query Inbox(
$first: Int!
$after: String
$filterBy: NotificationThreadFilters
$searchQuery: String
$avatarSize: Int!
) {
viewer {
__typename
id
...WebNotificationsEnabledFragment
notificationThreads(
first: $first
after: $after
filterBy: $filterBy
query: $searchQuery
) {
__typename
pageInfo {
__typename
hasNextPage
endCursor
}
totalCount
nodes {
__typename
...NotificationThreadCommonFieldsFragment
url
subject {
__typename
... on CheckSuite {
...InboxSubjectCheckSuiteFieldsFragment
}
... on WorkflowRun {
...InboxSubjectWorkflowRunFieldsFragment
}
... on Commit {
...InboxSubjectCommitFieldsFragment
}
... on Gist {
...InboxSubjectGistFieldsFragment
}
... on TeamDiscussion {
...InboxSubjectTeamDiscussionFieldsFragment
}
... on Issue {
...InboxSubjectIssueFieldsFragment
}
... on PullRequest {
...InboxSubjectPullRequestFieldsFragment
}
... on Release {
...InboxSubjectReleaseFieldsFragment
}
... on RepositoryVulnerabilityAlert {
...InboxSubjectRepositoryVulnerabilityAlertFieldsFragment
}
... on RepositoryAdvisory {
...InboxSubjectRepositoryAdvisoryFieldsFragment
}
...InboxSubjectDiscussionFieldsFragment
... on RepositoryDependabotAlertsThread {
...InboxSubjectRepositoryDependabotAlertsThreadFieldsFragment
}
... on SecurityAdvisory {
...InboxSubjectSecurityAdvisoryFieldsFragment
}
}
}
}
}
}
fragment AvatarFragment on Actor {
__typename
avatarUrl(size: $avatarSize)
}
fragment InboxSubjectCheckSuiteFieldsFragment on CheckSuite {
__typename
id
url
conclusion
status
}
fragment InboxSubjectCommitFieldsFragment on Commit {
__typename
id
abbreviatedOid
url
repository {
__typename
id
owner {
__typename
id
login
}
name
}
}
fragment InboxSubjectDiscussionFieldsFragment on Discussion {
__typename
id
url
number
discussionStateReason: stateReason
answer {
__typename
id
}
category {
__typename
id
isAnswerable
}
repository {
__typename
id
isOrganizationDiscussionRepository
}
}
fragment InboxSubjectGistFieldsFragment on Gist {
__typename
url
id
}
fragment InboxSubjectIssueFieldsFragment on Issue {
__typename
id
number
issueState: state
stateReason
issueHtmlTitle: titleHTML
url
}
fragment InboxSubjectPullRequestFieldsFragment on PullRequest {
__typename
id
number
pullRequestHtmlTitle: titleHTML
url
...PullRequestStateIcon
}
fragment InboxSubjectReleaseFieldsFragment on Release {
__typename
id
tagName
url
}
fragment InboxSubjectRepositoryAdvisoryFieldsFragment on RepositoryAdvisory {
__typename
id
url
}
fragment InboxSubjectRepositoryDependabotAlertsThreadFieldsFragment on RepositoryDependabotAlertsThread {
__typename
id
notificationsPermalink
}
fragment InboxSubjectRepositoryVulnerabilityAlertFieldsFragment on RepositoryVulnerabilityAlert {
__typename
id
permalink
}
fragment InboxSubjectSecurityAdvisoryFieldsFragment on SecurityAdvisory {
__typename
id
ghsaId
notificationsPermalink
}
fragment InboxSubjectTeamDiscussionFieldsFragment on TeamDiscussion {
__typename
url
id
}
fragment InboxSubjectWorkflowRunFieldsFragment on WorkflowRun {
__typename
id
url
runNumber
workflow {
__typename
id
name
}
checkSuite {
__typename
id
}
}
fragment ListSubscribableFragment on Subscribable {
__typename
id
viewerSubscription
viewerCanSubscribe
}
fragment NotificationThreadCommonFieldsFragment on NotificationThread {
__typename
id
threadType
title
isUnread
unreadItemsCount
lastUpdatedAt
subscriptionStatus
summaryItemAuthor {
__typename
id
...AvatarFragment
}
summaryItemBody
isArchived
isSaved
reason
list {
__typename
...ListSubscribableFragment
... on Repository {
id
owner {
__typename
id
login
}
name
}
... on User {
id
login
userName: name
}
... on Team {
id
organization {
__typename
id
login
}
slug
}
... on Organization {
id
login
}
}
}
fragment PullRequestStateIcon on PullRequest {
__typename
pullRequestState: state
isDraft
mergeQueueEntry {
__typename
id
position
}
}
fragment WebNotificationsEnabledFragment on User {
__typename
notificationSettings {
__typename
getsParticipatingWeb
getsWatchingWeb
}
}
'{
"errors":
[
{
"path":
[
"query Inbox",
"viewer",
"notificationThreads",
"nodes",
"subject",
"... on RepositoryAdvisory"
],
"extensions":
{
"code": "undefinedType",
"typeName": "RepositoryAdvisory"
},
"locations":
[
{
"line": 59,
"column": 15
}
],
"message": "No such type RepositoryAdvisory, so it can't be a fragment condition"
},
{
"path":
[
"fragment InboxSubjectDiscussionFieldsFragment",
"repository",
"isOrganizationDiscussionRepository"
],
"extensions":
{
"code": "undefinedField",
"typeName": "Repository",
"fieldName": "isOrganizationDiscussionRepository"
},
"locations":
[
{
"line": 119,
"column": 9
}
],
"message": "Field 'isOrganizationDiscussionRepository' doesn't exist on type 'Repository'"
},
{
"path":
[
"fragment InboxSubjectRepositoryAdvisoryFieldsFragment"
],
"extensions":
{
"code": "undefinedType",
"typeName": "RepositoryAdvisory"
},
"locations":
[
{
"line": 150,
"column": 5
}
],
"message": "No such type RepositoryAdvisory, so it can't be a fragment condition"
},
{
"path":
[
"fragment InboxSubjectRepositoryVulnerabilityAlertFieldsFragment",
"permalink"
],
"extensions":
{
"code": "undefinedField",
"typeName": "RepositoryVulnerabilityAlert",
"fieldName": "permalink"
},
"locations":
[
{
"line": 163,
"column": 7
}
],
"message": "Field 'permalink' doesn't exist on type 'RepositoryVulnerabilityAlert'"
},
{
"path":
[
"fragment WebNotificationsEnabledFragment",
"notificationSettings"
],
"extensions":
{
"code": "undefinedField",
"typeName": "User",
"fieldName": "notificationSettings"
},
"locations":
[
{
"line": 259,
"column": 7
}
],
"message": "Field 'notificationSettings' doesn't exist on type 'User'"
}
]
}gh: No such type RepositoryAdvisory, so it can't be a fragment condition
Field 'isOrganizationDiscussionRepository' doesn't exist on type 'Repository'
No such type RepositoryAdvisory, so it can't be a fragment condition
Field 'permalink' doesn't exist on type 'RepositoryVulnerabilityAlert'
Field 'notificationSettings' doesn't exist on type 'User'