Skip to content

Commit 8b2656a

Browse files
feat: type discussion and notification tool outputs (#3388)
* feat: type discussion and notification tool outputs Migrate all eleven tools to typed registration and compact output DTOs. Preserve legacy text, parameter compatibility, pagination, and mutation validation while publishing honest modern output unions. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix: tighten discussion and notification output contracts Trim notification hypermedia, preserve useful HTML links, and record all modern schemas in canonical snapshots. Preserve source presence during discussion read normalization and cover the Copilot review regression alongside empty/null outputs, IFC labels, sanitization, and output enums. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * test: cover empty-object discussion read requests and modern-text==DTO expectations Add an explicit {} (fully-empty args) case to TestDiscussionReadRequiredArguments proving the normalizer never synthesizes placeholder owner/repo/discussionNumber values that would let an empty request satisfy SDK required-schema validation and reach GraphQL; verified both protocols reject it pre-handler with zero GraphQL calls (addresses readiness-audit re-flag of already-fixed Copilot review comment 4171698931 in 578e9929). Also record the pending modern-text==structuredContent DTO contract (2026-07-28 protocol) in test expectations; these assertions are intentionally red pending the coordinator's central once-marshal wrapper in pkg/inventory/typed_output.go, which this branch does not yet have. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(notifications): preserve plain status output content Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent 70891c0 commit 8b2656a

17 files changed

Lines changed: 1989 additions & 117 deletions

‎pkg/github/__toolsnaps__/discussion_comment_write.snap‎

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,5 +46,42 @@
4646
],
4747
"type": "object"
4848
},
49-
"name": "discussion_comment_write"
49+
"name": "discussion_comment_write",
50+
"outputSchema": {
51+
"oneOf": [
52+
{
53+
"additionalProperties": false,
54+
"properties": {
55+
"id": {
56+
"type": "string"
57+
},
58+
"url": {
59+
"type": "string"
60+
}
61+
},
62+
"required": [
63+
"id",
64+
"url"
65+
],
66+
"type": "object"
67+
},
68+
{
69+
"additionalProperties": false,
70+
"properties": {
71+
"discussionID": {
72+
"type": "string"
73+
},
74+
"discussionURL": {
75+
"type": "string"
76+
}
77+
},
78+
"required": [
79+
"discussionID",
80+
"discussionURL"
81+
],
82+
"type": "object"
83+
}
84+
],
85+
"type": "object"
86+
}
5087
}

‎pkg/github/__toolsnaps__/dismiss_notification.snap‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,17 @@
2626
],
2727
"type": "object"
2828
},
29-
"name": "dismiss_notification"
29+
"name": "dismiss_notification",
30+
"outputSchema": {
31+
"additionalProperties": false,
32+
"properties": {
33+
"message": {
34+
"type": "string"
35+
}
36+
},
37+
"required": [
38+
"message"
39+
],
40+
"type": "object"
41+
}
3042
}

‎pkg/github/__toolsnaps__/get_discussion.snap‎

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,62 @@
2727
],
2828
"type": "object"
2929
},
30-
"name": "get_discussion"
30+
"name": "get_discussion",
31+
"outputSchema": {
32+
"additionalProperties": false,
33+
"properties": {
34+
"answerChosenAt": {
35+
"description": "Answer selection time (RFC3339), when selected.",
36+
"type": [
37+
"null",
38+
"string"
39+
]
40+
},
41+
"body": {
42+
"type": "string"
43+
},
44+
"category": {
45+
"additionalProperties": false,
46+
"properties": {
47+
"name": {
48+
"type": "string"
49+
}
50+
},
51+
"required": [
52+
"name"
53+
],
54+
"type": "object"
55+
},
56+
"closed": {
57+
"type": "boolean"
58+
},
59+
"createdAt": {
60+
"description": "Creation time (RFC3339).",
61+
"type": "string"
62+
},
63+
"html_url": {
64+
"type": "string"
65+
},
66+
"isAnswered": {
67+
"type": "boolean"
68+
},
69+
"number": {
70+
"type": "integer"
71+
},
72+
"title": {
73+
"type": "string"
74+
}
75+
},
76+
"required": [
77+
"number",
78+
"title",
79+
"body",
80+
"html_url",
81+
"closed",
82+
"isAnswered",
83+
"createdAt",
84+
"category"
85+
],
86+
"type": "object"
87+
}
3188
}

‎pkg/github/__toolsnaps__/get_discussion_comments.snap‎

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,97 @@
4141
],
4242
"type": "object"
4343
},
44-
"name": "get_discussion_comments"
44+
"name": "get_discussion_comments",
45+
"outputSchema": {
46+
"additionalProperties": false,
47+
"properties": {
48+
"comments": {
49+
"items": {
50+
"additionalProperties": false,
51+
"properties": {
52+
"body": {
53+
"type": "string"
54+
},
55+
"id": {
56+
"type": "string"
57+
},
58+
"isAnswer": {
59+
"type": "boolean"
60+
},
61+
"replies": {
62+
"items": {
63+
"additionalProperties": false,
64+
"properties": {
65+
"body": {
66+
"type": "string"
67+
},
68+
"id": {
69+
"type": "string"
70+
},
71+
"isAnswer": {
72+
"type": "boolean"
73+
}
74+
},
75+
"required": [
76+
"id",
77+
"body"
78+
],
79+
"type": "object"
80+
},
81+
"type": [
82+
"null",
83+
"array"
84+
]
85+
},
86+
"replyTotalCount": {
87+
"description": "Total replies, including replies beyond the returned maximum of 100.",
88+
"type": "integer"
89+
}
90+
},
91+
"required": [
92+
"id",
93+
"body"
94+
],
95+
"type": "object"
96+
},
97+
"type": [
98+
"null",
99+
"array"
100+
]
101+
},
102+
"pageInfo": {
103+
"additionalProperties": false,
104+
"properties": {
105+
"endCursor": {
106+
"type": "string"
107+
},
108+
"hasNextPage": {
109+
"type": "boolean"
110+
},
111+
"hasPreviousPage": {
112+
"type": "boolean"
113+
},
114+
"startCursor": {
115+
"type": "string"
116+
}
117+
},
118+
"required": [
119+
"hasNextPage",
120+
"hasPreviousPage",
121+
"startCursor",
122+
"endCursor"
123+
],
124+
"type": "object"
125+
},
126+
"totalCount": {
127+
"type": "integer"
128+
}
129+
},
130+
"required": [
131+
"comments",
132+
"pageInfo",
133+
"totalCount"
134+
],
135+
"type": "object"
136+
}
45137
}

‎pkg/github/__toolsnaps__/get_notification_details.snap‎

Lines changed: 126 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,130 @@
1717
],
1818
"type": "object"
1919
},
20-
"name": "get_notification_details"
20+
"name": "get_notification_details",
21+
"outputSchema": {
22+
"additionalProperties": false,
23+
"properties": {
24+
"id": {
25+
"type": [
26+
"null",
27+
"string"
28+
]
29+
},
30+
"last_read_at": {
31+
"description": "Last acknowledgement time (RFC3339).",
32+
"type": [
33+
"null",
34+
"string"
35+
]
36+
},
37+
"reason": {
38+
"enum": [
39+
"approval_requested",
40+
"assign",
41+
"author",
42+
"ci_activity",
43+
"comment",
44+
"invitation",
45+
"manual",
46+
"member_feature_requested",
47+
"mention",
48+
"review_requested",
49+
"security_alert",
50+
"security_advisory_credit",
51+
"state_change",
52+
"subscribed",
53+
"team_mention"
54+
],
55+
"type": [
56+
"null",
57+
"string"
58+
]
59+
},
60+
"repository": {
61+
"additionalProperties": false,
62+
"properties": {
63+
"full_name": {
64+
"type": [
65+
"null",
66+
"string"
67+
]
68+
},
69+
"html_url": {
70+
"type": [
71+
"null",
72+
"string"
73+
]
74+
},
75+
"id": {
76+
"type": [
77+
"null",
78+
"integer"
79+
]
80+
},
81+
"name": {
82+
"type": [
83+
"null",
84+
"string"
85+
]
86+
},
87+
"private": {
88+
"type": [
89+
"null",
90+
"boolean"
91+
]
92+
}
93+
},
94+
"type": [
95+
"null",
96+
"object"
97+
]
98+
},
99+
"subject": {
100+
"additionalProperties": false,
101+
"properties": {
102+
"title": {
103+
"type": [
104+
"null",
105+
"string"
106+
]
107+
},
108+
"type": {
109+
"enum": [
110+
"CheckSuite",
111+
"Commit",
112+
"Discussion",
113+
"Issue",
114+
"PullRequest",
115+
"Release",
116+
"RepositoryInvitation",
117+
"SecurityAdvisory"
118+
],
119+
"type": [
120+
"null",
121+
"string"
122+
]
123+
}
124+
},
125+
"type": [
126+
"null",
127+
"object"
128+
]
129+
},
130+
"unread": {
131+
"type": [
132+
"null",
133+
"boolean"
134+
]
135+
},
136+
"updated_at": {
137+
"description": "Last update time (RFC3339).",
138+
"type": [
139+
"null",
140+
"string"
141+
]
142+
}
143+
},
144+
"type": "object"
145+
}
21146
}

0 commit comments

Comments
 (0)