@slates-integrations/github 0.2.0-rc.7 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/docs/SPEC.md CHANGED
@@ -1,11 +1,227 @@
1
- Now I have enough information to write the specification. Let me compile everything.
2
-
3
- # Slates Specification for GitHub
1
+ # GitHub Integration Specification
4
2
 
5
3
  ## Overview
6
4
 
7
5
  GitHub is a cloud-based platform for version control and collaboration using Git. It provides hosting for software repositories along with features for issue tracking, code review, project management, CI/CD (GitHub Actions), and package hosting. GitHub offers both REST and GraphQL APIs for programmatic access to its platform resources.
8
6
 
7
+ ## Notable Tool Contracts
8
+
9
+ - `create_repository` creates a repository in the authenticated user's account unless
10
+ `organization` is provided. `private` defaults to `true`; pass `false` explicitly to
11
+ create a public repository. `autoInit` initializes the repository with a README.
12
+ - `merge_pull_request` accepts the optional snake-case fields `commit_title`,
13
+ `commit_message`, and `merge_method`. Supported merge methods are `merge`, `squash`,
14
+ and `rebase`.
15
+ - `list_issues` uses GraphQL cursor pagination. Pass `pageInfo.endCursor` from one
16
+ response as `after` to fetch the next page. `state` accepts `OPEN` or `CLOSED` and
17
+ returns both states when omitted. Labels are supplied as an array. Custom issue
18
+ fields can be filtered with `field_filters` entries containing `field_name` and
19
+ `value`.
20
+ - `issue_read` consolidates issue detail, comment, hierarchy, and label reads. Its
21
+ `get` method includes best-effort parent/child relationship signals and custom issue
22
+ field values.
23
+ - `pull_request_read` consolidates pull request detail, diff, status, file, commit,
24
+ review-thread, review, conversation-comment, and check-run reads.
25
+ - `list_pull_requests` is for repository filters such as state and branches. To filter
26
+ pull requests by author, use `search` with type `issues` and GitHub search qualifiers
27
+ such as `is:pr author:<login>`.
28
+ - `star_repository` deliberately consolidates both star and unstar operations through
29
+ its required `action` field.
30
+ - `search` covers organizations through GitHub's user-search endpoint: use type
31
+ `users` with the `type:org` qualifier.
32
+ - `create_branch` creates a branch from `from_branch`, or from the repository's
33
+ default branch when the source is omitted.
34
+ - `push_files` writes multiple plain-text files atomically in one commit through the
35
+ Git tree, commit, and ref APIs. If the requested branch is absent, it is created
36
+ from the default branch.
37
+ - `get_repository_tree` reads a tree at an optional SHA, branch, or tag, supports
38
+ recursive traversal, and can filter returned entries by a path prefix.
39
+ - `update_pull_request_branch` starts GitHub's base-branch update for a pull request;
40
+ `expectedHeadSha` provides optimistic concurrency protection.
41
+ - `sub_issue_write` supports `add`, `remove`, and `reprioritize`. `sub_issue_id` is
42
+ the issue database ID rather than the issue number, and reprioritization requires
43
+ exactly one of `after_id` or `before_id`.
44
+ - `get_global_security_advisory` and `list_global_security_advisories` expose the
45
+ public GitHub Advisory Database with GHSA, CVE, ecosystem, severity, CWE,
46
+ withdrawn-state, affected-package, and date filters.
47
+
48
+ ## Added Tool Coverage
49
+
50
+ The tools below expose focused GitHub capabilities with stable identifiers and
51
+ structured results. A classic OAuth token must include the listed scope. For
52
+ fine-grained tokens and GitHub Apps, grant the equivalent repository,
53
+ organization, notification, security, or Projects permission.
54
+
55
+ ### Security and code quality
56
+
57
+ | Tool | OAuth scope | User outcome |
58
+ | --- | --- | --- |
59
+ | `get_code_scanning_alert` | `security_events` | Read one code scanning alert by repository and alert number, including rule, severity, location, state, and dismissal details. |
60
+ | `list_code_scanning_alerts` | `security_events` | Triage repository alerts by state, Git ref, severity, scanning tool, and page. The state defaults to `open`. |
61
+ | `get_dependabot_alert` | `security_events` | Read one Dependabot alert by repository and alert number, including dependency, advisory, severity, and remediation details. |
62
+ | `list_dependabot_alerts` | `security_events` | List Dependabot alerts by state or severity and continue with the returned cursor. The state defaults to `open`. |
63
+ | `get_secret_scanning_alert` | `security_events` | Read one secret scanning alert by repository and alert number, including secret type, location, state, and resolution. |
64
+ | `list_secret_scanning_alerts` | `security_events` | List secret scanning alerts by state, resolution, secret type, and page. |
65
+ | `list_repository_security_advisories` | `security_events` | List one repository's private security advisories by state, sort field, and direction. |
66
+ | `list_org_repository_security_advisories` | `security_events` | List repository security advisories across an organization by state, sort field, and direction. |
67
+ | `get_code_quality_finding` | `repo` or `public_repo` | Read one code quality finding by repository and finding number, including diagnostic and remediation details when available. |
68
+
69
+ ### Notifications
70
+
71
+ | Tool | OAuth scope | User outcome |
72
+ | --- | --- | --- |
73
+ | `list_notifications` | `notifications` | List the authenticated user's notification inbox, optionally including read items, limiting to participating threads, filtering by RFC3339 timestamps, or limiting to one repository. `owner` and `repo` must be supplied together. |
74
+ | `get_notification_details` | `notifications` | Read one notification thread by `notificationID`; use `list_notifications` first when the ID is unknown. |
75
+ | `manage_notification_subscription` | `notifications` | Watch, ignore, or delete a notification-thread subscription by `notificationID`. |
76
+ | `manage_repository_notification_subscription` | `notifications` | Watch, ignore, or delete notification subscription settings for a repository. |
77
+ | `mark_all_notifications_read` | `notifications` | Mark notifications read through `lastReadAt`, defaulting to the current time. Supplying `owner` and `repo` together limits the operation to that repository. |
78
+ | `dismiss_notification` | `notifications` | Mark a thread `read` or `done`; `done` removes it from the notification inbox. |
79
+
80
+ ### Discussions
81
+
82
+ | Tool | OAuth scope | User outcome |
83
+ | --- | --- | --- |
84
+ | `list_discussion_categories` | `repo` or `public_repo` | List category node IDs and names for a repository. Omitting `repo` reads organization-level categories from the owner's `.github` repository. |
85
+ | `list_discussions` | `repo` or `public_repo` | List discussions with cursor pagination, category filtering, optional page-local title/body filtering, and paired ordering controls. `orderBy` and `direction` must be supplied together. |
86
+ | `get_discussion` | `repo` or `public_repo` | Read a discussion by repository-local number with its body, category, answer state, author, timestamps, and permalink. |
87
+ | `get_discussion_comments` | `repo` or `public_repo` | Read a cursor-paginated page of top-level comments. `includeReplies: true` also returns up to 100 replies per top-level comment. |
88
+ | `discussion_comment_write` | `repo` or `public_repo` | Add, reply to, update, or delete discussion comments and mark or unmark accepted answers. See the conditional fields below. |
89
+
90
+ `discussion_comment_write` uses these conditional fields:
91
+
92
+ - `add` requires `owner`, `repo`, `discussionNumber`, and `body`.
93
+ - `reply` also requires the parent `commentNodeID`. Discussions support one
94
+ level of nested replies.
95
+ - `update` requires `commentNodeID` and `body`.
96
+ - `delete`, `mark_answer`, and `unmark_answer` require `commentNodeID`.
97
+
98
+ ### GitHub Projects
99
+
100
+ | Tool | OAuth scope | User outcome |
101
+ | --- | --- | --- |
102
+ | `projects_list` | `read:project` | List user or organization projects, or list fields, items, and status updates for a project. Methods other than `list_projects` require `project_number`. Item reads accept either `fields` IDs or `field_names`, never both. |
103
+ | `projects_get` | `read:project` | Get a project, field, item, or status update. Project, field, and item reads require `owner` and `project_number`; field and item reads also require their corresponding ID. A status-update read requires only `status_update_id`. |
104
+ | `projects_write` | `project` | Create a project, add/update/delete items, publish status updates, or create an iteration field. Each method validates its own owner, project, item, field, and date inputs before changing data. |
105
+
106
+ For `projects_write`, `create_project` requires `owner_type` and `title`.
107
+ `add_project_item` requires `project_number`, `item_type`, `item_owner`,
108
+ `item_repo`, and the matching issue or pull request number.
109
+ `update_project_item` requires `project_number`, `updated_field`, and exactly
110
+ one item locator: `item_id` or `item_owner` + `item_repo` + `issue_number`.
111
+ `delete_project_item` requires `project_number` and `item_id`.
112
+ `create_iteration_field` requires `project_number`, `field_name`,
113
+ `start_date`, and a positive `iteration_duration`.
114
+
115
+ ### Repository and account reads
116
+
117
+ | Tool | OAuth scope | User outcome |
118
+ | --- | --- | --- |
119
+ | `fork_repository` | `repo` or `public_repo` | Fork a repository to the authenticated account or the optional `organization`, returning created-fork metadata or an `in_progress` status for asynchronous forks. |
120
+ | `list_starred_repositories` | `repo` or `public_repo` | List repositories starred by `username`, or by the authenticated user when it is omitted, with sort direction and page controls. |
121
+
122
+ ## Expanded Consolidated Contracts
123
+
124
+ All tools in this section require `repo` or `public_repo`.
125
+
126
+ ### `manage_workflow`
127
+
128
+ `manage_workflow` covers GitHub Actions listing, inspection, downloads, job-log
129
+ troubleshooting, and run operations while retaining the existing `action`
130
+ values `list_workflows`, `list_runs`, `get_run`, `trigger`, `cancel`, `rerun`,
131
+ and `list_jobs`.
132
+
133
+ - Listing methods are `list_workflows`, `list_workflow_runs`,
134
+ `list_workflow_jobs`, and `list_workflow_run_artifacts`.
135
+ `list_workflow_runs` optionally accepts a workflow ID or filename as
136
+ `resource_id` plus `workflow_runs_filter`. Job and artifact listing require
137
+ the workflow run ID as `resource_id`. Job listing accepts
138
+ `workflow_jobs_filter.filter` as `latest` or `all`.
139
+ - Read methods are `get_workflow`, `get_workflow_run`, `get_workflow_job`,
140
+ `get_workflow_run_usage`, `get_workflow_run_logs_url`, and
141
+ `download_workflow_run_artifact`. Each requires `resource_id`; only
142
+ `get_workflow` accepts a workflow filename instead of a numeric ID.
143
+ - Run methods are `run_workflow`, `rerun_workflow_run`, `rerun_failed_jobs`,
144
+ `cancel_workflow_run`, and `delete_workflow_run_logs`. `run_workflow`
145
+ requires `workflow_id` and `ref`; all other run methods require `run_id`.
146
+ - For one job's logs, omit `method` and provide `job_id`. For all failed jobs
147
+ in a run, provide `run_id` with `failed_only: true`. `tail_lines` defaults
148
+ to 500. With `return_content: false`, the result contains authenticated
149
+ download endpoints. With `return_content: true`, each requested log is a
150
+ downloadable text file and the structured result contains only file name,
151
+ MIME type, byte count, line counts, truncation state, and job IDs.
152
+ - Downloaded workflow artifacts are returned as ZIP files. The structured
153
+ result contains artifact ID, file name, MIME type, and byte count rather
154
+ than embedding the archive bytes.
155
+
156
+ ### `comment_on_issue`
157
+
158
+ `comment_on_issue` accepts `issue_number` or the existing `issueNumber` alias
159
+ and can create a comment, add a reaction, or do both in one call.
160
+
161
+ - At least one of `body` or `reaction` is required.
162
+ - Omitting `comment_id` targets the issue or pull request itself.
163
+ - Providing `comment_id` targets that issue comment, requires `reaction`, and
164
+ cannot be combined with `body`. The comment is verified to belong to the
165
+ requested issue before the reaction is added.
166
+ - Review-comment reactions belong in `review_pull_request`, not this tool.
167
+
168
+ ### `manage_issue`
169
+
170
+ `manage_issue` supports explicit `create` and `update` methods. Existing calls
171
+ may omit `method`; providing either issue-number field selects update behavior.
172
+
173
+ - `create` requires `title`; `update` requires `issue_number` or
174
+ `issueNumber`.
175
+ - `type` uses an issue type returned by `list_issue_types`.
176
+ - Every `issue_fields` entry requires `field_name` and exactly one of
177
+ `value`, `field_option_name`, or `delete: true`.
178
+ - Closing as a duplicate requires `state: "closed"`,
179
+ `state_reason: "duplicate"`, and `duplicate_of`. `duplicate_of` is not
180
+ accepted for other state reasons.
181
+ - `stateReason` remains an accepted existing alias. If both state-reason
182
+ fields are supplied, their values must agree.
183
+
184
+ ### `manage_labels`
185
+
186
+ `manage_labels` creates, updates, renames, deletes, and continues to list
187
+ repository labels through the existing `action: "list"` operation.
188
+
189
+ - Supply either `method` or `action`. If both are present, they must agree.
190
+ - Create, update, and delete require `name`; create also requires `color`.
191
+ - Update requires at least one of `new_name`, `color`, or `description`.
192
+
193
+ ### `manage_pull_request`
194
+
195
+ Omitting `pullNumber` creates a pull request and requires `title`, `head`, and
196
+ `base`. Providing `pullNumber` updates a pull request and requires at least one
197
+ change among title, body, state, base, draft state, maintainer-edit permission,
198
+ or reviewers.
199
+
200
+ `reviewers` accepts GitHub usernames and `ORG/team-slug` team identifiers.
201
+ `draft: true` converts an existing pull request to draft; `draft: false` marks
202
+ it ready for review. `maintainer_can_modify` is the preferred field, while
203
+ `maintainerCanModify` remains accepted; if both are supplied, they must agree.
204
+
205
+ ### `review_pull_request`
206
+
207
+ Supply either `method` or the existing `action`, never both.
208
+
209
+ - Existing actions submit `APPROVE`, `REQUEST_CHANGES`, or `COMMENT` reviews,
210
+ or request user/team reviewers.
211
+ - `create` requires `pullNumber`; omitting `event` creates a pending review.
212
+ Providing `event` submits it immediately.
213
+ - `submit_pending` requires `pullNumber` and `event`; `delete_pending`
214
+ requires `pullNumber`.
215
+ - `resolve_thread` and `unresolve_thread` require the GraphQL `threadId`
216
+ returned by `pull_request_read` with `method: "get_review_comments"`.
217
+ - `add_comment_to_pending_review` requires `pullNumber`, `path`, `body`, and
218
+ `subjectType`. A `FILE` comment omits all line fields. A `LINE` comment
219
+ requires positive `line` and `side`; a range additionally requires
220
+ `startLine` and `startSide`, with matching sides and `startLine < line`.
221
+ - `add_reply_to_pull_request_comment` requires a numeric `commentId` and at
222
+ least one of `body` or `reaction`. A text reply also requires `pullNumber`;
223
+ a reaction-only call can use the comment ID alone.
224
+
9
225
  ## Authentication
10
226
 
11
227
  GitHub supports several authentication methods for API access:
@@ -143,73 +359,99 @@ In addition to the REST API, GitHub provides a GraphQL API (v4) that allows more
143
359
 
144
360
  ## Events
145
361
 
146
- Webhooks provide a way for notifications to be delivered to an external web server whenever certain events occur on GitHub. Webhooks let you subscribe to events happening in a software system and automatically receive a delivery of data to your server whenever those events occur.
147
-
148
- You can create webhooks in a repository to subscribe to events that occur in that repository. You can create webhooks to subscribe to events that occur in a specific repository, organization, GitHub Marketplace account, GitHub Sponsors account, or GitHub App.
149
-
150
- Webhooks are configured with a payload URL, content type (JSON or form), and an optional secret for signature verification. The webhook signature header is the HMAC hex digest of the request body, generated using the SHA-256 hash function and the secret as the HMAC key.
151
-
152
- ### Code & Repository Events
153
-
154
- - **Push:** Triggered when commits are pushed to a branch or tag.
155
- - **Create / Delete:** Triggered when a branch or tag is created or deleted.
156
- - **Repository:** Triggered when a repository is created, deleted, archived, made public/private, or transferred.
157
- - **Fork:** Triggered when a repository is forked.
158
- - **Release:** Triggered when a release is published, edited, or deleted (including pre-releases).
159
- - **Commit Comment:** Triggered when a comment is made on a commit.
160
-
161
- ### Pull Request Events
162
-
163
- - **Pull Request:** Triggered for activity on pull requests (opened, closed, merged, assigned, labeled, review requested, etc.). Configurable by action type.
164
- - **Pull Request Review:** Triggered when a review is submitted, edited, or dismissed.
165
- - **Pull Request Review Comment:** Triggered for comments on a pull request diff.
166
- - **Pull Request Review Thread:** Triggered when a comment thread on a pull request is resolved or unresolved.
167
-
168
- ### Issue Events
169
-
170
- - **Issues:** Triggered for issue activity (opened, edited, closed, assigned, labeled, etc.).
171
- - **Issue Comment:** Triggered when a comment is created, edited, or deleted on an issue or pull request.
172
- - **Label:** Triggered when a label is created, edited, or deleted.
173
- - **Milestone:** Triggered when a milestone is created, closed, edited, or deleted.
174
-
175
- ### CI/CD and Checks Events
176
-
177
- - **Check Run / Check Suite:** Triggered for check run and check suite lifecycle events (created, completed, rerequested).
178
- - **Workflow Job:** Triggered when a GitHub Actions workflow job is queued, in progress, or completed.
179
- - **Workflow Run:** Triggered when a workflow run is requested, completed, or in progress.
180
- - **Deployment / Deployment Status:** Triggered when a deployment is created or its status changes.
181
- - **Status:** Triggered when the status of a commit changes.
182
-
183
- ### Organization and Team Events
184
-
185
- - **Organization:** Triggered for organization-level events (member added/removed, renamed, etc.).
186
- - **Team:** Triggered when a team is created, deleted, edited, or has members/repos added/removed.
187
- - **Membership:** Triggered when a user is added to or removed from a team.
188
- - **Member:** Triggered when a collaborator is added to a repository.
189
-
190
- ### Security Events
191
-
192
- - **Code Scanning Alert:** Triggered when a code scanning alert is created, fixed, or dismissed.
193
- - **Secret Scanning Alert:** Triggered when a secret scanning alert is created, resolved, or reopened.
194
- - **Dependabot Alert:** Triggered for Dependabot vulnerability alert activity.
195
- - **Repository Vulnerability Alert:** Triggered when a security vulnerability is detected.
196
-
197
- ### Discussion Events
198
-
199
- - **Discussion:** Triggered for GitHub Discussions activity (created, edited, answered, etc.).
200
- - **Discussion Comment:** Triggered when a comment on a discussion is created, edited, or deleted.
201
-
202
- ### Project Events
203
-
204
- - **Projects V2 Item:** Triggered when an item in a GitHub Project is created, edited, or deleted.
205
-
206
- ### Other Events
207
-
208
- - **Star:** Triggered when a repository is starred or unstarred.
209
- - **Watch:** Triggered when a user watches a repository.
210
- - **Wiki (Gollum):** Triggered when a wiki page is created or updated.
211
- - **Page Build:** Triggered when a GitHub Pages site is built.
212
- - **Package:** Triggered when a package is published or updated in GitHub Packages.
213
- - **Sponsorship:** Triggered for GitHub Sponsors activity.
214
- - **Marketplace Purchase:** Triggered for GitHub Marketplace purchase activity.
215
- - **Ping:** A special event sent when a webhook is first created to verify the connection.
362
+ The integration implements one automatically managed repository event source with
363
+ 23 separate event triggers. Its setup, event catalog, permission requirements,
364
+ and output examples are documented in [Repository events](../README.md#repository-events).
365
+
366
+ ### Configuration and lifecycle
367
+
368
+ Connection configuration is empty. Callback enablement starts automatic discovery,
369
+ including for portal-created instances. Discovery uses `GET /user/repos` with 100
370
+ repositories per page ordered by full name. Because the runtime starts every
371
+ 15-minute rediscovery with a null page token and keeps no state between cycles,
372
+ conditional requests cannot reduce cost; discovery is bounded instead. The page
373
+ token is `{ page, probes }` and is validated: at most 10 pages (1,000 repositories)
374
+ are scanned per cycle, and at most 50 non-admin repositories per cycle are probed
375
+ with `GET /repos/{owner}/{repo}/hooks` for webhook access (custom roles). Admin
376
+ repositories (`permissions.admin`) are eligible without a probe; archived repositories
377
+ are skipped; non-admin repositories beyond the probe budget are skipped. Reaching
378
+ either limit logs a warning (`github_webhook_probe_limit`, `github_webhook_page_limit`).
379
+ Worst case per connection per cycle is 60 requests. Discovery deduplicates repository
380
+ IDs per page and preserves the next page token even when no repositories on a page
381
+ qualify. The runtime deduplicates stable targets across pages and connections.
382
+ Resource-level 403/404 responses are skipped; rate limits are recognised from GitHub's
383
+ `x-ratelimit-remaining`/`retry-after` headers (429, or 403 with those headers) and
384
+ propagate together with authentication errors and other service failures. Read access
385
+ does not prove fine-grained token write access; creation reports missing write
386
+ permissions. No manual target-selection or webhook configuration is exposed.
387
+
388
+ A target is identified by its normalized GitHub instance URL and immutable repository
389
+ ID. Registration resolves its current name and checks identity before creating an
390
+ active JSON hook with a random secret, TLS verification, and the exact event catalog.
391
+ Connections in the same tenant share the target. Cleanup uses the saved hook ID and
392
+ checks repository identity before deletion. A DELETE 404 is accepted only after an
393
+ authorized paginated hooks list confirms absence. Repository lookup 404 remains
394
+ retryable because it can indicate lost access to a private repository.
395
+
396
+ The companion hub changes rescan active automatic subscriptions every 15 minutes,
397
+ continue empty discovery pages, initialize cleanup with connection auth/config, and
398
+ keep provider cleanup failures retryable. Shared hooks remain until the last callback
399
+ is removed. No provider-specific behavior is added to the hub. Deploy those runtime
400
+ changes alongside this integration for lifecycle behavior; SDK tests alone do not
401
+ prove deployed runtime cleanup or delivery.
402
+
403
+ ### Event contract
404
+
405
+ Every trigger exposes `{ deliveryId, event, action, payload }`. The event name
406
+ matches GitHub's header, action is a string or `null`, and payload is the complete
407
+ GitHub JSON object. Typed resource schemas preserve additional fields, including
408
+ nested fields. Mapping uses the delivery snapshot without authenticated lookups.
409
+ The callback ID is the delivery ID; its type is `event.action` or `event` when
410
+ there is no action. A merge is `pull_request.closed` with
411
+ `payload.pull_request.merged === true`, not a separate action.
412
+
413
+ Incoming requests require POST, a valid SHA-256 signature over the original
414
+ body, a GUID delivery ID, a matching `X-GitHub-Hook-ID`, installation-target
415
+ headers naming the saved repository, and a payload `repository.id` equal to the
416
+ saved repository. Malformed or unauthenticated requests are rejected. Every rejected
417
+ or ignored delivery is logged with a reason code (`github_webhook_*`) and the event,
418
+ delivery, and hook headers; payloads and secrets are never logged. Valid pings and
419
+ unsupported event families are acknowledged without callbacks. Repeated deliveries
420
+ use the same idempotency key; GitHub does not supply a signed delivery timestamp.
421
+
422
+ Repository hooks support only `created`/`completed` check runs and `completed`
423
+ check suites. Repository creation across an organization cannot be observed by a
424
+ hook attached to an existing repository. Discussions and Dependabot depend on
425
+ repository feature availability. Unsupported events on older Enterprise versions
426
+ cause registration errors; coverage is never silently reduced.
427
+
428
+ ### Verification
429
+
430
+ SDK contract tests live in the enterprise repository next to the live suite
431
+ (`tests/integrations/github/triggers*.test.ts`, run with `bun run triggers:test -- github`),
432
+ not in this package. They exercise all event families, payload preservation, request
433
+ verification, target discovery (including the page and probe limits), registration,
434
+ and cleanup. A second suite sweeps all 169 GitHub-recorded payload examples for the
435
+ 23 implemented families, vendored verbatim from `octokit/webhooks` at a pinned commit
436
+ (`tests/integrations/github/__fixtures__/octokit-webhooks`), through verification, selection, and mapping
437
+ with deep equality. That repository is unmaintained and its successor
438
+ (`octokit/openapi-webhooks`) publishes GitHub's OpenAPI schemas rather than example
439
+ deliveries, so the examples are real but dated (last updated 2024-10); they prove the
440
+ schemas accept recorded shapes. A third suite covers the current contract: it checks
441
+ every event schema against a pinned structural skeleton of GitHub's OpenAPI webhook
442
+ description (`tests/integrations/github/__fixtures__/github-openapi-webhooks`, generated by
443
+ `scripts/github-webhook-schema-skeleton.ts` at the repo root) for all 114 operations
444
+ GitHub's description marks as deliverable to repository hooks (a per-event flag, so it
445
+ includes the app-only check actions the trigger descriptions exclude; checking them can
446
+ only make the schemas looser), asserting the schemas are never stricter than GitHub:
447
+ every field required here is required by GitHub, every null GitHub may send is
448
+ accepted, and every JSON type or enum value GitHub may send parses. Local negative
449
+ tests are needed because GitHub cannot
450
+ send intentionally forged signatures or invalid repository identities. Private live
451
+ coverage creates, reads back, and deletes a real hook on a disposable repository.
452
+ This lifecycle check uses a non-resolving receiver URL and does not claim to verify
453
+ end-to-end callback delivery.
454
+
455
+ Provider references: [repository webhook API](https://docs.github.com/en/rest/repos/webhooks),
456
+ [event payloads](https://docs.github.com/en/webhooks/webhook-events-and-payloads),
457
+ and [signature verification](https://docs.github.com/en/webhooks/using-webhooks/validating-webhook-deliveries).
package/package.json CHANGED
@@ -4,17 +4,21 @@
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "build": "bunx @vercel/ncc build src/index.ts -o dist -m -s",
7
+ "test": "vitest run --config vitest.config.ts --passWithNoTests",
7
8
  "typecheck": "tsc --noEmit"
8
9
  },
9
10
  "dependencies": {
11
+ "@lowerdeck/error": "^1.1.0",
10
12
  "@types/node": "^20",
11
- "slates": "1.0.0-rc.14",
13
+ "slates": "1.0.0-rc.23",
12
14
  "zod": "^4.2"
13
15
  },
14
16
  "devDependencies": {
15
- "typescript": "^5"
17
+ "@slates/test": "1.0.0-rc.21",
18
+ "typescript": "^5",
19
+ "vitest": "^3.1.2"
16
20
  },
17
- "version": "0.2.0-rc.7",
21
+ "version": "0.2.2",
18
22
  "files": [
19
23
  "dist/**",
20
24
  "docs/**",