@orgloop/connector-github 0.1.0

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/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 OrgLoop contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,116 @@
1
+ # @orgloop/connector-github
2
+
3
+ Polls the GitHub REST API for pull request, issue, and CI activity on a repository.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @orgloop/connector-github
9
+ ```
10
+
11
+ ## Configuration
12
+
13
+ ```yaml
14
+ sources:
15
+ - id: github-eng
16
+ connector: "@orgloop/connector-github"
17
+ config:
18
+ repo: "my-org/my-repo" # owner/repo to watch
19
+ token: "${GITHUB_TOKEN}" # PAT or fine-grained token (env var ref)
20
+ events: # which event types to poll
21
+ - pull_request.review_submitted
22
+ - pull_request_review_comment
23
+ - issue_comment
24
+ - pull_request.closed
25
+ - pull_request.merged
26
+ - workflow_run.completed
27
+ authors: # optional — only include events by these users
28
+ - alice
29
+ - bob
30
+ poll:
31
+ interval: "5m"
32
+ ```
33
+
34
+ ### Config options
35
+
36
+ | Field | Type | Required | Description |
37
+ |-------|------|----------|-------------|
38
+ | `repo` | `string` | yes | GitHub repository in `owner/repo` format |
39
+ | `token` | `string` | yes | GitHub PAT. Supports `${ENV_VAR}` syntax |
40
+ | `events` | `string[]` | yes | Event types to poll (see below) |
41
+ | `authors` | `string[]` | no | Filter to events authored by these GitHub logins |
42
+
43
+ ## Events emitted
44
+
45
+ All events are emitted as OrgLoop `resource.changed` type.
46
+
47
+ ### Supported event types
48
+
49
+ | Event string | What it polls | OrgLoop type |
50
+ |---|---|---|
51
+ | `pull_request.review_submitted` | PR reviews (approve, request changes, comment) | `resource.changed` |
52
+ | `pull_request_review_comment` | Inline review comments on PRs | `resource.changed` |
53
+ | `issue_comment` | Comments on issues and PRs | `resource.changed` |
54
+ | `pull_request.closed` | Closed PRs | `resource.changed` |
55
+ | `pull_request.merged` | Merged PRs (polled via closed PRs) | `resource.changed` |
56
+ | `workflow_run.completed` | Failed GitHub Actions workflow runs | `resource.changed` |
57
+
58
+ ### Example event payload (PR review)
59
+
60
+ ```json
61
+ {
62
+ "id": "evt_a1b2c3d4e5f67890",
63
+ "timestamp": "2025-01-15T10:30:00.000Z",
64
+ "source": "github:my-org/my-repo",
65
+ "type": "resource.changed",
66
+ "provenance": {
67
+ "platform": "github",
68
+ "platform_event": "pull_request.review_submitted",
69
+ "author": "alice",
70
+ "author_type": "team_member",
71
+ "repo": "my-org/my-repo",
72
+ "pr_number": 42,
73
+ "url": "https://github.com/my-org/my-repo/pull/42#pullrequestreview-123",
74
+ "review_state": "approved"
75
+ },
76
+ "payload": {
77
+ "action": "review_submitted",
78
+ "review_state": "approved",
79
+ "review_body": "LGTM!",
80
+ "pr_title": "Add feature X",
81
+ "pr_number": 42
82
+ }
83
+ }
84
+ ```
85
+
86
+ ## Example route
87
+
88
+ ```yaml
89
+ routes:
90
+ - name: pr-review-to-openclaw
91
+ when:
92
+ source: github-eng
93
+ events:
94
+ - resource.changed
95
+ filter:
96
+ provenance.platform_event: pull_request.review_submitted
97
+ then:
98
+ actor: openclaw-agent
99
+ ```
100
+
101
+ ## Auth / prerequisites
102
+
103
+ - A GitHub Personal Access Token (classic or fine-grained) with read access to the target repository.
104
+ - For fine-grained tokens, the following permissions are needed:
105
+ - **Pull requests**: Read
106
+ - **Issues**: Read
107
+ - **Actions**: Read (for `workflow_run.completed`)
108
+ - Set the token as an environment variable (e.g., `GITHUB_TOKEN`) and reference it in the config with `${GITHUB_TOKEN}`.
109
+
110
+ ## Limitations / known issues
111
+
112
+ - **Polling only** -- this connector uses the GitHub REST API, not webhooks. Events may be delayed up to one poll interval.
113
+ - **Rate limits** -- GitHub API rate limits apply (5,000 requests/hour for authenticated requests). The connector backs off gracefully on 429 responses but high-frequency polling of repos with many open PRs can consume quota quickly.
114
+ - **Per-page limits** -- Review polling fetches up to 30 recently updated PRs and their reviews. Very active repos may miss reviews on older PRs.
115
+ - **Bot detection** -- Authors with `[bot]` suffix or GitHub `type: "Bot"` are classified as `author_type: "bot"`.
116
+ - **No webhook receiver** -- Unlike `connector-webhook`, this connector has no webhook handler; it only polls.
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @orgloop/connector-github — GitHub source connector registration.
3
+ */
4
+ import type { ConnectorRegistration } from '@orgloop/sdk';
5
+ export default function register(): ConnectorRegistration;
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAI1D,MAAM,CAAC,OAAO,UAAU,QAAQ,IAAI,qBAAqB,CAiBxD"}
package/dist/index.js ADDED
@@ -0,0 +1,24 @@
1
+ /**
2
+ * @orgloop/connector-github — GitHub source connector registration.
3
+ */
4
+ import { GitHubSource } from './source.js';
5
+ import { GitHubCredentialValidator } from './validator.js';
6
+ export default function register() {
7
+ return {
8
+ id: 'github',
9
+ source: GitHubSource,
10
+ setup: {
11
+ env_vars: [
12
+ {
13
+ name: 'GITHUB_TOKEN',
14
+ description: 'GitHub personal access token with repo scope',
15
+ help_url: 'https://github.com/settings/tokens/new?scopes=repo',
16
+ },
17
+ ],
18
+ },
19
+ credential_validators: {
20
+ GITHUB_TOKEN: new GitHubCredentialValidator(),
21
+ },
22
+ };
23
+ }
24
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAE3D,MAAM,CAAC,OAAO,UAAU,QAAQ;IAC/B,OAAO;QACN,EAAE,EAAE,QAAQ;QACZ,MAAM,EAAE,YAAY;QACpB,KAAK,EAAE;YACN,QAAQ,EAAE;gBACT;oBACC,IAAI,EAAE,cAAc;oBACpB,WAAW,EAAE,8CAA8C;oBAC3D,QAAQ,EAAE,oDAAoD;iBAC9D;aACD;SACD;QACD,qBAAqB,EAAE;YACtB,YAAY,EAAE,IAAI,yBAAyB,EAAE;SAC7C;KACD,CAAC;AACH,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * GitHub API response normalizer — maps GitHub events to OrgLoop events.
3
+ */
4
+ import type { OrgLoopEvent } from '@orgloop/sdk';
5
+ /** Normalize a PR review event */
6
+ export declare function normalizePullRequestReview(sourceId: string, review: Record<string, unknown>, pr: Record<string, unknown>, repo: Record<string, unknown>): OrgLoopEvent;
7
+ /** Normalize a PR review comment event */
8
+ export declare function normalizePullRequestReviewComment(sourceId: string, comment: Record<string, unknown>, pr: Record<string, unknown>, repo: Record<string, unknown>): OrgLoopEvent;
9
+ /** Normalize an issue comment on a PR */
10
+ export declare function normalizeIssueComment(sourceId: string, comment: Record<string, unknown>, issue: Record<string, unknown>, repo: Record<string, unknown>): OrgLoopEvent;
11
+ /** Normalize a PR closed/merged event */
12
+ export declare function normalizePullRequestClosed(sourceId: string, pr: Record<string, unknown>, repo: Record<string, unknown>): OrgLoopEvent;
13
+ /** Normalize a workflow run completion (failure) */
14
+ export declare function normalizeWorkflowRunFailed(sourceId: string, run: Record<string, unknown>, repo: Record<string, unknown>): OrgLoopEvent;
15
+ /** Normalize a PR opened event */
16
+ export declare function normalizePullRequestOpened(sourceId: string, pr: Record<string, unknown>, repo: Record<string, unknown>): OrgLoopEvent;
17
+ /** Normalize a PR draft→ready transition */
18
+ export declare function normalizePullRequestReadyForReview(sourceId: string, pr: Record<string, unknown>, repo: Record<string, unknown>): OrgLoopEvent;
19
+ /** Normalize a check suite completion event */
20
+ export declare function normalizeCheckSuiteCompleted(sourceId: string, suite: Record<string, unknown>, repo: Record<string, unknown>): OrgLoopEvent;
21
+ //# sourceMappingURL=normalizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalizer.d.ts","sourceRoot":"","sources":["../src/normalizer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAc,YAAY,EAAE,MAAM,cAAc,CAAC;AAiB7D,kCAAkC;AAClC,wBAAgB,0BAA0B,CACzC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC3B,YAAY,CA2Bd;AAED,0CAA0C;AAC1C,wBAAgB,iCAAiC,CAChD,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC3B,YAAY,CA2Bd;AAED,yCAAyC;AACzC,wBAAgB,qBAAqB,CACpC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC3B,YAAY,CA0Bd;AAED,yCAAyC;AACzC,wBAAgB,0BAA0B,CACzC,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC3B,YAAY,CA2Bd;AAED,oDAAoD;AACpD,wBAAgB,0BAA0B,CACzC,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC3B,YAAY,CAyBd;AAED,kCAAkC;AAClC,wBAAgB,0BAA0B,CACzC,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC3B,YAAY,CA2Bd;AAED,4CAA4C;AAC5C,wBAAgB,kCAAkC,CACjD,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC3B,YAAY,CA0Bd;AAED,+CAA+C;AAC/C,wBAAgB,4BAA4B,CAC3C,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC3B,YAAY,CAwBd"}
@@ -0,0 +1,221 @@
1
+ /**
2
+ * GitHub API response normalizer — maps GitHub events to OrgLoop events.
3
+ */
4
+ import { buildEvent } from '@orgloop/sdk';
5
+ /** Detect if a GitHub user is a bot by checking for [bot] suffix or type field */
6
+ function detectAuthorType(login, type) {
7
+ if (type === 'Bot' || login.endsWith('[bot]')) {
8
+ return 'bot';
9
+ }
10
+ return 'team_member';
11
+ }
12
+ /** Extract the login of a PR owner */
13
+ function extractPrAuthor(pr) {
14
+ const prUser = pr.user;
15
+ return prUser?.login ?? 'unknown';
16
+ }
17
+ /** Normalize a PR review event */
18
+ export function normalizePullRequestReview(sourceId, review, pr, repo) {
19
+ const user = review.user;
20
+ return buildEvent({
21
+ source: sourceId,
22
+ type: 'resource.changed',
23
+ provenance: {
24
+ platform: 'github',
25
+ platform_event: 'pull_request.review_submitted',
26
+ author: user?.login ?? 'unknown',
27
+ author_type: detectAuthorType(user?.login ?? '', user?.type),
28
+ pr_author: extractPrAuthor(pr),
29
+ repo: repo.full_name ?? '',
30
+ pr_number: pr.number,
31
+ url: review.html_url ?? '',
32
+ review_state: review.state,
33
+ },
34
+ payload: {
35
+ action: 'review_submitted',
36
+ review_state: review.state,
37
+ review_body: review.body,
38
+ pr_title: pr.title,
39
+ pr_number: pr.number,
40
+ },
41
+ });
42
+ }
43
+ /** Normalize a PR review comment event */
44
+ export function normalizePullRequestReviewComment(sourceId, comment, pr, repo) {
45
+ const user = comment.user;
46
+ return buildEvent({
47
+ source: sourceId,
48
+ type: 'resource.changed',
49
+ provenance: {
50
+ platform: 'github',
51
+ platform_event: 'pull_request_review_comment',
52
+ author: user?.login ?? 'unknown',
53
+ author_type: detectAuthorType(user?.login ?? '', user?.type),
54
+ pr_author: extractPrAuthor(pr),
55
+ repo: repo.full_name ?? '',
56
+ pr_number: pr.number,
57
+ url: comment.html_url ?? '',
58
+ },
59
+ payload: {
60
+ action: 'review_comment',
61
+ comment_body: comment.body,
62
+ pr_title: pr.title,
63
+ pr_number: pr.number,
64
+ diff_hunk: comment.diff_hunk,
65
+ path: comment.path,
66
+ },
67
+ });
68
+ }
69
+ /** Normalize an issue comment on a PR */
70
+ export function normalizeIssueComment(sourceId, comment, issue, repo) {
71
+ const user = comment.user;
72
+ return buildEvent({
73
+ source: sourceId,
74
+ type: 'resource.changed',
75
+ provenance: {
76
+ platform: 'github',
77
+ platform_event: 'issue_comment',
78
+ author: user?.login ?? 'unknown',
79
+ author_type: detectAuthorType(user?.login ?? '', user?.type),
80
+ pr_author: extractPrAuthor(issue),
81
+ repo: repo.full_name ?? '',
82
+ pr_number: issue.number,
83
+ url: comment.html_url ?? '',
84
+ },
85
+ payload: {
86
+ action: 'issue_comment',
87
+ comment_body: comment.body,
88
+ issue_title: issue.title,
89
+ issue_number: issue.number,
90
+ is_pull_request: !!issue.pull_request,
91
+ },
92
+ });
93
+ }
94
+ /** Normalize a PR closed/merged event */
95
+ export function normalizePullRequestClosed(sourceId, pr, repo) {
96
+ const user = pr.user;
97
+ const merged = pr.merged;
98
+ return buildEvent({
99
+ source: sourceId,
100
+ type: 'resource.changed',
101
+ provenance: {
102
+ platform: 'github',
103
+ platform_event: merged ? 'pull_request.merged' : 'pull_request.closed',
104
+ author: user?.login ?? 'unknown',
105
+ author_type: detectAuthorType(user?.login ?? '', user?.type),
106
+ pr_author: extractPrAuthor(pr),
107
+ repo: repo.full_name ?? '',
108
+ pr_number: pr.number,
109
+ url: pr.html_url ?? '',
110
+ },
111
+ payload: {
112
+ action: merged ? 'merged' : 'closed',
113
+ pr_title: pr.title,
114
+ pr_number: pr.number,
115
+ merged,
116
+ merged_by: merged ? pr.merged_by?.login : undefined,
117
+ },
118
+ });
119
+ }
120
+ /** Normalize a workflow run completion (failure) */
121
+ export function normalizeWorkflowRunFailed(sourceId, run, repo) {
122
+ const actor = run.actor;
123
+ return buildEvent({
124
+ source: sourceId,
125
+ type: 'resource.changed',
126
+ provenance: {
127
+ platform: 'github',
128
+ platform_event: 'workflow_run.completed',
129
+ author: actor?.login ?? 'unknown',
130
+ author_type: detectAuthorType(actor?.login ?? '', actor?.type),
131
+ repo: repo.full_name ?? '',
132
+ url: run.html_url ?? '',
133
+ },
134
+ payload: {
135
+ action: 'workflow_run_failed',
136
+ workflow_name: run.name,
137
+ run_number: run.run_number,
138
+ conclusion: run.conclusion,
139
+ head_branch: run.head_branch,
140
+ head_sha: run.head_sha,
141
+ },
142
+ });
143
+ }
144
+ /** Normalize a PR opened event */
145
+ export function normalizePullRequestOpened(sourceId, pr, repo) {
146
+ const user = pr.user;
147
+ return buildEvent({
148
+ source: sourceId,
149
+ type: 'resource.changed',
150
+ provenance: {
151
+ platform: 'github',
152
+ platform_event: 'pull_request.opened',
153
+ author: user?.login ?? 'unknown',
154
+ author_type: detectAuthorType(user?.login ?? '', user?.type),
155
+ pr_author: extractPrAuthor(pr),
156
+ repo: repo.full_name ?? '',
157
+ pr_number: pr.number,
158
+ url: pr.html_url ?? '',
159
+ },
160
+ payload: {
161
+ action: 'opened',
162
+ pr_title: pr.title,
163
+ pr_number: pr.number,
164
+ draft: pr.draft ?? false,
165
+ head_ref: pr.head ? pr.head.ref : undefined,
166
+ base_ref: pr.base ? pr.base.ref : undefined,
167
+ },
168
+ });
169
+ }
170
+ /** Normalize a PR draft→ready transition */
171
+ export function normalizePullRequestReadyForReview(sourceId, pr, repo) {
172
+ const user = pr.user;
173
+ return buildEvent({
174
+ source: sourceId,
175
+ type: 'resource.changed',
176
+ provenance: {
177
+ platform: 'github',
178
+ platform_event: 'pull_request.ready_for_review',
179
+ author: user?.login ?? 'unknown',
180
+ author_type: detectAuthorType(user?.login ?? '', user?.type),
181
+ pr_author: extractPrAuthor(pr),
182
+ repo: repo.full_name ?? '',
183
+ pr_number: pr.number,
184
+ url: pr.html_url ?? '',
185
+ },
186
+ payload: {
187
+ action: 'ready_for_review',
188
+ pr_title: pr.title,
189
+ pr_number: pr.number,
190
+ head_ref: pr.head ? pr.head.ref : undefined,
191
+ base_ref: pr.base ? pr.base.ref : undefined,
192
+ },
193
+ });
194
+ }
195
+ /** Normalize a check suite completion event */
196
+ export function normalizeCheckSuiteCompleted(sourceId, suite, repo) {
197
+ const app = suite.app;
198
+ return buildEvent({
199
+ source: sourceId,
200
+ type: 'resource.changed',
201
+ provenance: {
202
+ platform: 'github',
203
+ platform_event: 'check_suite.completed',
204
+ author: app?.slug ?? 'unknown',
205
+ author_type: 'bot',
206
+ repo: repo.full_name ?? '',
207
+ url: suite.url ?? '',
208
+ },
209
+ payload: {
210
+ action: 'check_suite_completed',
211
+ conclusion: suite.conclusion,
212
+ status: suite.status,
213
+ app_name: app?.name ?? app?.slug,
214
+ head_branch: suite.head_branch,
215
+ head_sha: suite.head_sha,
216
+ before: suite.before,
217
+ after: suite.after,
218
+ },
219
+ });
220
+ }
221
+ //# sourceMappingURL=normalizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalizer.js","sourceRoot":"","sources":["../src/normalizer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * GitHub source connector — polls GitHub API for repository events.
3
+ *
4
+ * Uses octokit.paginate() for all list endpoints to avoid data loss
5
+ * from silent truncation at page boundaries.
6
+ */
7
+ import type { PollResult, SourceConfig, SourceConnector } from '@orgloop/sdk';
8
+ export declare class GitHubSource implements SourceConnector {
9
+ readonly id = "github";
10
+ private octokit;
11
+ private owner;
12
+ private repo;
13
+ private events;
14
+ private authors;
15
+ private sourceId;
16
+ init(config: SourceConfig): Promise<void>;
17
+ poll(checkpoint: string | null): Promise<PollResult>;
18
+ /**
19
+ * Fetch all recently-updated PRs using pagination.
20
+ * Shared by pollReviews and pollReviewComments to avoid duplicate API calls.
21
+ */
22
+ private fetchUpdatedPulls;
23
+ private pollReviews;
24
+ private pollReviewComments;
25
+ private pollIssueComments;
26
+ private pollClosedPRs;
27
+ private pollOpenedPRs;
28
+ private pollReadyForReviewPRs;
29
+ private pollFailedWorkflowRuns;
30
+ private pollCheckSuites;
31
+ shutdown(): Promise<void>;
32
+ }
33
+ //# sourceMappingURL=source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../src/source.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAgB,UAAU,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAkC5F,qBAAa,YAAa,YAAW,eAAe;IACnD,QAAQ,CAAC,EAAE,YAAY;IACvB,OAAO,CAAC,OAAO,CAAW;IAC1B,OAAO,CAAC,KAAK,CAAM;IACnB,OAAO,CAAC,IAAI,CAAM;IAClB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,QAAQ,CAAM;IAEhB,IAAI,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAazC,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,UAAU,CAAC;IAuF1D;;;OAGG;YACW,iBAAiB;YAkBjB,WAAW;YAkCX,kBAAkB;YAoClB,iBAAiB;YAwBjB,aAAa;YAgBb,aAAa;YAgBb,qBAAqB;YAsBrB,sBAAsB;YActB,eAAe;IAqBvB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAG/B"}
package/dist/source.js ADDED
@@ -0,0 +1,271 @@
1
+ /**
2
+ * GitHub source connector — polls GitHub API for repository events.
3
+ *
4
+ * Uses octokit.paginate() for all list endpoints to avoid data loss
5
+ * from silent truncation at page boundaries.
6
+ */
7
+ import { Octokit } from '@octokit/rest';
8
+ import { normalizeCheckSuiteCompleted, normalizeIssueComment, normalizePullRequestClosed, normalizePullRequestOpened, normalizePullRequestReadyForReview, normalizePullRequestReview, normalizePullRequestReviewComment, normalizeWorkflowRunFailed, } from './normalizer.js';
9
+ /** Resolve env var references like ${GITHUB_TOKEN} */
10
+ function resolveEnvVar(value) {
11
+ const match = value.match(/^\$\{(.+)\}$/);
12
+ if (match) {
13
+ const envValue = process.env[match[1]];
14
+ if (!envValue) {
15
+ throw new Error(`Environment variable ${match[1]} is not set`);
16
+ }
17
+ return envValue;
18
+ }
19
+ return value;
20
+ }
21
+ export class GitHubSource {
22
+ id = 'github';
23
+ octokit;
24
+ owner = '';
25
+ repo = '';
26
+ events = [];
27
+ authors = [];
28
+ sourceId = '';
29
+ async init(config) {
30
+ const cfg = config.config;
31
+ const [owner, repo] = cfg.repo.split('/');
32
+ this.owner = owner;
33
+ this.repo = repo;
34
+ this.events = cfg.events ?? [];
35
+ this.authors = cfg.authors ?? [];
36
+ this.sourceId = config.id;
37
+ const token = resolveEnvVar(cfg.token);
38
+ this.octokit = new Octokit({ auth: token });
39
+ }
40
+ async poll(checkpoint) {
41
+ const since = checkpoint ? new Date(checkpoint).toISOString() : null;
42
+ const events = [];
43
+ let latestTimestamp = since ?? new Date(0).toISOString();
44
+ try {
45
+ // Fetch PRs once for methods that need them (reviews + review comments)
46
+ const needsPulls = this.events.includes('pull_request.review_submitted') ||
47
+ this.events.includes('pull_request_review_comment');
48
+ let pulls = [];
49
+ if (needsPulls) {
50
+ pulls = await this.fetchUpdatedPulls(since);
51
+ }
52
+ if (this.events.includes('pull_request.review_submitted')) {
53
+ const reviews = await this.pollReviews(since, pulls);
54
+ events.push(...reviews);
55
+ }
56
+ if (this.events.includes('pull_request_review_comment')) {
57
+ const comments = await this.pollReviewComments(since, pulls);
58
+ events.push(...comments);
59
+ }
60
+ if (this.events.includes('issue_comment')) {
61
+ const comments = await this.pollIssueComments(since);
62
+ events.push(...comments);
63
+ }
64
+ if (this.events.includes('pull_request.closed') ||
65
+ this.events.includes('pull_request.merged')) {
66
+ const prs = await this.pollClosedPRs(since);
67
+ events.push(...prs);
68
+ }
69
+ if (this.events.includes('pull_request.opened')) {
70
+ const prs = await this.pollOpenedPRs(since);
71
+ events.push(...prs);
72
+ }
73
+ if (this.events.includes('pull_request.ready_for_review')) {
74
+ const prs = await this.pollReadyForReviewPRs(since);
75
+ events.push(...prs);
76
+ }
77
+ if (this.events.includes('workflow_run.completed')) {
78
+ const runs = await this.pollFailedWorkflowRuns(since);
79
+ events.push(...runs);
80
+ }
81
+ if (this.events.includes('check_suite.completed')) {
82
+ const suites = await this.pollCheckSuites(since);
83
+ events.push(...suites);
84
+ }
85
+ }
86
+ catch (err) {
87
+ const error = err;
88
+ if (error.status === 429) {
89
+ // Rate limited — back off, return what we have
90
+ return { events: [], checkpoint: latestTimestamp };
91
+ }
92
+ if (error.status === 401 || error.status === 403) {
93
+ console.error(`[github] Auth error: ${error.message}`);
94
+ return { events: [], checkpoint: latestTimestamp };
95
+ }
96
+ throw err;
97
+ }
98
+ // Find the latest timestamp among all events
99
+ for (const event of events) {
100
+ if (event.timestamp > latestTimestamp) {
101
+ latestTimestamp = event.timestamp;
102
+ }
103
+ }
104
+ // Filter by authors if configured
105
+ const filtered = this.authors.length > 0
106
+ ? events.filter((e) => this.authors.includes(e.provenance.author ?? ''))
107
+ : events;
108
+ return { events: filtered, checkpoint: latestTimestamp };
109
+ }
110
+ /**
111
+ * Fetch all recently-updated PRs using pagination.
112
+ * Shared by pollReviews and pollReviewComments to avoid duplicate API calls.
113
+ */
114
+ async fetchUpdatedPulls(since) {
115
+ const allPulls = await this.octokit.paginate(this.octokit.pulls.list, {
116
+ owner: this.owner,
117
+ repo: this.repo,
118
+ state: 'all',
119
+ sort: 'updated',
120
+ direction: 'desc',
121
+ per_page: 100,
122
+ });
123
+ if (!since)
124
+ return allPulls;
125
+ // Filter to PRs updated after the checkpoint
126
+ return allPulls.filter((pr) => pr.updated_at && pr.updated_at >= since);
127
+ }
128
+ async pollReviews(since, pulls) {
129
+ const events = [];
130
+ const repoData = { full_name: `${this.owner}/${this.repo}` };
131
+ for (const pr of pulls) {
132
+ try {
133
+ const reviews = await this.octokit.paginate(this.octokit.pulls.listReviews, {
134
+ owner: this.owner,
135
+ repo: this.repo,
136
+ pull_number: pr.number,
137
+ per_page: 100,
138
+ });
139
+ for (const review of reviews) {
140
+ const submitted = review.submitted_at;
141
+ if (!since || (submitted && submitted > since)) {
142
+ events.push(normalizePullRequestReview(this.sourceId, review, pr, repoData));
143
+ }
144
+ }
145
+ }
146
+ catch {
147
+ // Skip individual PR errors
148
+ }
149
+ }
150
+ return events;
151
+ }
152
+ async pollReviewComments(since, pulls) {
153
+ const events = [];
154
+ const repoData = { full_name: `${this.owner}/${this.repo}` };
155
+ for (const pr of pulls) {
156
+ try {
157
+ const comments = await this.octokit.paginate(this.octokit.pulls.listReviewComments, {
158
+ owner: this.owner,
159
+ repo: this.repo,
160
+ pull_number: pr.number,
161
+ ...(since ? { since } : {}),
162
+ per_page: 100,
163
+ });
164
+ for (const comment of comments) {
165
+ const updatedAt = comment.updated_at;
166
+ if (!since || updatedAt > since) {
167
+ events.push(normalizePullRequestReviewComment(this.sourceId, comment, pr, repoData));
168
+ }
169
+ }
170
+ }
171
+ catch {
172
+ // Skip individual PR errors
173
+ }
174
+ }
175
+ return events;
176
+ }
177
+ async pollIssueComments(since) {
178
+ const comments = await this.octokit.paginate(this.octokit.issues.listCommentsForRepo, {
179
+ owner: this.owner,
180
+ repo: this.repo,
181
+ ...(since ? { since } : {}),
182
+ sort: 'updated',
183
+ direction: 'desc',
184
+ per_page: 100,
185
+ });
186
+ const repoData = { full_name: `${this.owner}/${this.repo}` };
187
+ return comments
188
+ .filter((c) => !since || c.updated_at > since)
189
+ .map((comment) => {
190
+ const issueNumber = comment.issue_url?.split('/').pop();
191
+ return normalizeIssueComment(this.sourceId, comment, { number: Number(issueNumber), title: '' }, repoData);
192
+ });
193
+ }
194
+ async pollClosedPRs(since) {
195
+ const pulls = await this.octokit.paginate(this.octokit.pulls.list, {
196
+ owner: this.owner,
197
+ repo: this.repo,
198
+ state: 'closed',
199
+ sort: 'updated',
200
+ direction: 'desc',
201
+ per_page: 100,
202
+ });
203
+ const repoData = { full_name: `${this.owner}/${this.repo}` };
204
+ return pulls
205
+ .filter((pr) => pr.closed_at && (!since || pr.closed_at > since))
206
+ .map((pr) => normalizePullRequestClosed(this.sourceId, pr, repoData));
207
+ }
208
+ async pollOpenedPRs(since) {
209
+ const pulls = await this.octokit.paginate(this.octokit.pulls.list, {
210
+ owner: this.owner,
211
+ repo: this.repo,
212
+ state: 'open',
213
+ sort: 'created',
214
+ direction: 'desc',
215
+ per_page: 100,
216
+ });
217
+ const repoData = { full_name: `${this.owner}/${this.repo}` };
218
+ return pulls
219
+ .filter((pr) => pr.created_at && (!since || pr.created_at > since))
220
+ .map((pr) => normalizePullRequestOpened(this.sourceId, pr, repoData));
221
+ }
222
+ async pollReadyForReviewPRs(since) {
223
+ // Fetch recently updated open PRs that are NOT drafts.
224
+ // We detect draft→ready by finding non-draft PRs updated since the checkpoint.
225
+ // This works because GitHub updates `updated_at` when draft status changes.
226
+ const pulls = await this.octokit.paginate(this.octokit.pulls.list, {
227
+ owner: this.owner,
228
+ repo: this.repo,
229
+ state: 'open',
230
+ sort: 'updated',
231
+ direction: 'desc',
232
+ per_page: 100,
233
+ });
234
+ const repoData = { full_name: `${this.owner}/${this.repo}` };
235
+ return pulls
236
+ .filter((pr) => pr.draft === false && pr.updated_at && (!since || pr.updated_at > since))
237
+ .map((pr) => normalizePullRequestReadyForReview(this.sourceId, pr, repoData));
238
+ }
239
+ async pollFailedWorkflowRuns(since) {
240
+ const data = await this.octokit.paginate(this.octokit.actions.listWorkflowRunsForRepo, {
241
+ owner: this.owner,
242
+ repo: this.repo,
243
+ status: 'failure',
244
+ per_page: 100,
245
+ });
246
+ const repoData = { full_name: `${this.owner}/${this.repo}` };
247
+ return data
248
+ .filter((run) => !since || run.updated_at > since)
249
+ .map((run) => normalizeWorkflowRunFailed(this.sourceId, run, repoData));
250
+ }
251
+ async pollCheckSuites(since) {
252
+ // Check suites endpoint requires a ref; use the default branch
253
+ // We use the repository-level check-suites-for-ref with HEAD
254
+ const { data } = await this.octokit.checks.listSuitesForRef({
255
+ owner: this.owner,
256
+ repo: this.repo,
257
+ ref: 'HEAD',
258
+ per_page: 100,
259
+ });
260
+ const repoData = { full_name: `${this.owner}/${this.repo}` };
261
+ return data.check_suites
262
+ .filter((suite) => suite.status === 'completed' &&
263
+ suite.updated_at &&
264
+ (!since || suite.updated_at > since))
265
+ .map((suite) => normalizeCheckSuiteCompleted(this.sourceId, suite, repoData));
266
+ }
267
+ async shutdown() {
268
+ // Nothing to clean up
269
+ }
270
+ }
271
+ //# sourceMappingURL=source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source.js","sourceRoot":"","sources":["../src/source.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * GitHub credential validator — probes the GitHub API to verify a token works.
3
+ *
4
+ * Stage 2 connector maturity: validates that GITHUB_TOKEN actually authenticates
5
+ * and reports the associated user identity and OAuth scopes.
6
+ */
7
+ import type { CredentialValidator } from '@orgloop/sdk';
8
+ export declare class GitHubCredentialValidator implements CredentialValidator {
9
+ validate(value: string): Promise<{
10
+ valid: boolean;
11
+ identity?: string;
12
+ scopes?: string[];
13
+ error?: string;
14
+ }>;
15
+ }
16
+ //# sourceMappingURL=validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAExD,qBAAa,yBAA0B,YAAW,mBAAmB;IAC9D,QAAQ,CACb,KAAK,EAAE,MAAM,GACX,OAAO,CAAC;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAoDpF"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * GitHub credential validator — probes the GitHub API to verify a token works.
3
+ *
4
+ * Stage 2 connector maturity: validates that GITHUB_TOKEN actually authenticates
5
+ * and reports the associated user identity and OAuth scopes.
6
+ */
7
+ export class GitHubCredentialValidator {
8
+ async validate(value) {
9
+ try {
10
+ const controller = new AbortController();
11
+ const timeout = setTimeout(() => controller.abort(), 5000);
12
+ const response = await fetch('https://api.github.com/user', {
13
+ headers: {
14
+ Authorization: `Bearer ${value}`,
15
+ Accept: 'application/vnd.github+json',
16
+ 'User-Agent': 'orgloop-doctor',
17
+ },
18
+ signal: controller.signal,
19
+ });
20
+ clearTimeout(timeout);
21
+ if (response.status === 401) {
22
+ return { valid: false, error: 'Invalid token (401 Unauthorized)' };
23
+ }
24
+ if (!response.ok) {
25
+ return {
26
+ valid: false,
27
+ error: `GitHub API returned ${response.status} ${response.statusText}`,
28
+ };
29
+ }
30
+ const data = (await response.json());
31
+ const scopeHeader = response.headers.get('x-oauth-scopes');
32
+ const scopes = scopeHeader
33
+ ? scopeHeader
34
+ .split(',')
35
+ .map((s) => s.trim())
36
+ .filter(Boolean)
37
+ : undefined;
38
+ return {
39
+ valid: true,
40
+ identity: data.login ? `user: @${data.login}` : undefined,
41
+ scopes,
42
+ };
43
+ }
44
+ catch (err) {
45
+ if (err instanceof DOMException && err.name === 'AbortError') {
46
+ return { valid: true, error: 'Validation timed out (GitHub may be unreachable)' };
47
+ }
48
+ // Fail-open: network errors treated as "ok with a note"
49
+ return {
50
+ valid: true,
51
+ error: `Could not reach GitHub API: ${err instanceof Error ? err.message : String(err)}`,
52
+ };
53
+ }
54
+ }
55
+ }
56
+ //# sourceMappingURL=validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.js","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,OAAO,yBAAyB;IACrC,KAAK,CAAC,QAAQ,CACb,KAAa;QAEb,IAAI,CAAC;YACJ,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;YACzC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,CAAC;YAE3D,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,6BAA6B,EAAE;gBAC3D,OAAO,EAAE;oBACR,aAAa,EAAE,UAAU,KAAK,EAAE;oBAChC,MAAM,EAAE,6BAA6B;oBACrC,YAAY,EAAE,gBAAgB;iBAC9B;gBACD,MAAM,EAAE,UAAU,CAAC,MAAM;aACzB,CAAC,CAAC;YAEH,YAAY,CAAC,OAAO,CAAC,CAAC;YAEtB,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBAC7B,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,kCAAkC,EAAE,CAAC;YACpE,CAAC;YAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBAClB,OAAO;oBACN,KAAK,EAAE,KAAK;oBACZ,KAAK,EAAE,uBAAuB,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE;iBACtE,CAAC;YACH,CAAC;YAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAuB,CAAC;YAC3D,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;YAC3D,MAAM,MAAM,GAAG,WAAW;gBACzB,CAAC,CAAC,WAAW;qBACV,KAAK,CAAC,GAAG,CAAC;qBACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;qBACpB,MAAM,CAAC,OAAO,CAAC;gBAClB,CAAC,CAAC,SAAS,CAAC;YAEb,OAAO;gBACN,KAAK,EAAE,IAAI;gBACX,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS;gBACzD,MAAM;aACN,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,IAAI,GAAG,YAAY,YAAY,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBAC9D,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,kDAAkD,EAAE,CAAC;YACnF,CAAC;YACD,wDAAwD;YACxD,OAAO;gBACN,KAAK,EAAE,IAAI;gBACX,KAAK,EAAE,+BAA+B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;aACxF,CAAC;QACH,CAAC;IACF,CAAC;CACD"}
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@orgloop/connector-github",
3
+ "version": "0.1.0",
4
+ "description": "OrgLoop GitHub connector — poll for PR activity, CI status, issues",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "dependencies": {
9
+ "@octokit/rest": "^21.0.0",
10
+ "@orgloop/sdk": "0.1.0"
11
+ },
12
+ "orgloop": {
13
+ "type": "connector",
14
+ "provides": [
15
+ "source"
16
+ ],
17
+ "id": "github"
18
+ },
19
+ "files": [
20
+ "dist"
21
+ ],
22
+ "publishConfig": {
23
+ "access": "public"
24
+ },
25
+ "license": "MIT",
26
+ "scripts": {
27
+ "build": "tsc",
28
+ "clean": "rm -rf dist",
29
+ "typecheck": "tsc --noEmit",
30
+ "test": "vitest run"
31
+ }
32
+ }