@mastra/github-signals 0.0.0 → 0.1.1-alpha.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/CHANGELOG.md +16 -0
- package/dist/index.cjs +235 -38
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +34 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +235 -38
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export declare const GITHUB_SUBSCRIBE_PR_TAG = "github-subscribe-pr";
|
|
|
8
8
|
export declare const GITHUB_UNSUBSCRIBE_PR_TAG = "github-unsubscribe-pr";
|
|
9
9
|
export declare const GITHUB_SYNC_STATUS_TAG = "github-sync-status";
|
|
10
10
|
export declare const GITHUB_SIGNALS_METADATA_KEY = "githubSignals";
|
|
11
|
+
export type GithubPermission = 'admin' | 'maintain' | 'write' | 'triage' | 'read' | 'none';
|
|
11
12
|
export type GithubPRSubscription = {
|
|
12
13
|
owner: string;
|
|
13
14
|
repo: string;
|
|
@@ -64,6 +65,14 @@ export type GithubPullRequestCheckSnapshot = {
|
|
|
64
65
|
detailsUrl?: string;
|
|
65
66
|
updatedAt?: string;
|
|
66
67
|
};
|
|
68
|
+
export type GithubPullRequestCommentSnapshot = {
|
|
69
|
+
author?: string;
|
|
70
|
+
authorType?: string;
|
|
71
|
+
isBot?: boolean;
|
|
72
|
+
body?: string;
|
|
73
|
+
url?: string;
|
|
74
|
+
updatedAt?: string;
|
|
75
|
+
};
|
|
67
76
|
type GithubPullRequestCheckInput = GithubPullRequestCheckSnapshot & {
|
|
68
77
|
source: 'check' | 'workflow';
|
|
69
78
|
};
|
|
@@ -87,6 +96,11 @@ export type GithubPullRequestSnapshot = {
|
|
|
87
96
|
latestCommentAuthor?: string;
|
|
88
97
|
latestCommentAuthorType?: string;
|
|
89
98
|
latestCommentIsBot?: boolean;
|
|
99
|
+
latestCommentBody?: string;
|
|
100
|
+
latestCommentUrl?: string;
|
|
101
|
+
latestCommentUpdatedAt?: string;
|
|
102
|
+
/** Recent comments newest-first, used to fall back when the latest comment is unauthorized noise. */
|
|
103
|
+
latestComments?: GithubPullRequestCommentSnapshot[];
|
|
90
104
|
};
|
|
91
105
|
export type GithubSignalsSyncClient = {
|
|
92
106
|
syncPullRequest(input: GithubSignalsSyncInput): Promise<GithubSignalsSyncResult>;
|
|
@@ -111,6 +125,9 @@ export type GithubSignalsThreadStore = {
|
|
|
111
125
|
thread: StorageThreadType;
|
|
112
126
|
}): Promise<StorageThreadType>;
|
|
113
127
|
};
|
|
128
|
+
export type GithubPermissionResolver = {
|
|
129
|
+
getPermission(owner: string, repo: string, user: string): Promise<GithubPermission | undefined>;
|
|
130
|
+
};
|
|
114
131
|
export type GithubSignalsOptions = {
|
|
115
132
|
owner?: string;
|
|
116
133
|
repo?: string;
|
|
@@ -123,18 +140,32 @@ export type GithubSignalsOptions = {
|
|
|
123
140
|
repositoryResolver?: GithubRepositoryResolver;
|
|
124
141
|
threadStore?: GithubSignalsThreadStore;
|
|
125
142
|
getNotificationStreamOptions?: GithubSignalAgentOptions['getNotificationStreamOptions'];
|
|
143
|
+
/** Permissions that authorize a human commenter to trigger notifications (default: admin, maintain, write). */
|
|
144
|
+
authorizedPermissions?: GithubPermission[];
|
|
145
|
+
/** Bot logins authorized to trigger notifications (default: coderabbitai[bot], devin-ai-integration[bot]). */
|
|
146
|
+
authorizedBots?: string[];
|
|
147
|
+
/** Bot logins whose comments should be ignored and NOT trigger notifications. */
|
|
148
|
+
ignoredBots?: string[];
|
|
149
|
+
/** Custom resolver for looking up collaborator permissions (default: gh api). */
|
|
150
|
+
permissionResolver?: GithubPermissionResolver;
|
|
126
151
|
};
|
|
127
152
|
export type GithubSubscriptionsChangedEvent = {
|
|
128
153
|
threadId: string;
|
|
129
154
|
resourceId: string;
|
|
130
155
|
subscriptions: GithubPRSubscription[];
|
|
131
156
|
};
|
|
157
|
+
export type GithubPollingChangedEvent = {
|
|
158
|
+
threadId: string;
|
|
159
|
+
resourceId: string;
|
|
160
|
+
running: boolean;
|
|
161
|
+
};
|
|
132
162
|
type GithubSubscriptionsChangedHandler = (event: GithubSubscriptionsChangedEvent) => void;
|
|
163
|
+
type GithubPollingChangedHandler = (event: GithubPollingChangedEvent) => void;
|
|
133
164
|
type GithubSignalAgent = {
|
|
134
165
|
sendSignal(signal: AgentSignalInput, target: unknown): {
|
|
135
166
|
accepted: unknown;
|
|
136
167
|
};
|
|
137
|
-
sendNotificationSignal?(notification: unknown, target: unknown): {
|
|
168
|
+
sendNotificationSignal?(notification: unknown | unknown[], target: unknown): {
|
|
138
169
|
accepted?: unknown;
|
|
139
170
|
} | Promise<unknown>;
|
|
140
171
|
};
|
|
@@ -200,6 +231,7 @@ export declare class GithubSignals extends SignalProvider<'github-signals'> {
|
|
|
200
231
|
getInputProcessors(): InputProcessorOrWorkflow[];
|
|
201
232
|
getOutputProcessors(): OutputProcessorOrWorkflow[];
|
|
202
233
|
onSubscriptionsChanged(handler: GithubSubscriptionsChangedHandler): void;
|
|
234
|
+
onPollingChanged(handler: GithubPollingChangedHandler): void;
|
|
203
235
|
__registerMastra(mastra: Mastra<any, any, any, any, any, any, any, any, any, any>): void;
|
|
204
236
|
syncThreadNow(input: GithubPollingThread): Promise<number>;
|
|
205
237
|
subscribeThreadToPR(input: GithubPollingThread & {
|
|
@@ -213,6 +245,7 @@ export declare class GithubSignals extends SignalProvider<'github-signals'> {
|
|
|
213
245
|
}): Promise<boolean>;
|
|
214
246
|
stopPollingForThread(input: GithubPollingThread): void;
|
|
215
247
|
isPollingThread(input: GithubPollingThread): boolean;
|
|
248
|
+
isPollingThreadRunning(input: GithubPollingThread): boolean;
|
|
216
249
|
getPollIntervalMs(): number;
|
|
217
250
|
stopAllPolling(): void;
|
|
218
251
|
pollThreadNow(input: GithubPollingThread): Promise<number>;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -20,6 +20,10 @@ var GITHUB_SUBSCRIBE_PR_TAG = "github-subscribe-pr";
|
|
|
20
20
|
var GITHUB_UNSUBSCRIBE_PR_TAG = "github-unsubscribe-pr";
|
|
21
21
|
var GITHUB_SYNC_STATUS_TAG = "github-sync-status";
|
|
22
22
|
var GITHUB_SIGNALS_METADATA_KEY = "githubSignals";
|
|
23
|
+
var DEFAULT_AUTHORIZED_PERMISSIONS = ["admin", "maintain", "write"];
|
|
24
|
+
var DEFAULT_AUTHORIZED_BOTS = ["coderabbitai[bot]", "devin-ai-integration[bot]"];
|
|
25
|
+
var PERMISSION_CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
26
|
+
var AUTHOR_GATED_NOTIFICATION_KINDS = /* @__PURE__ */ new Set(["pull-request-activity", "pull-request-review-activity"]);
|
|
23
27
|
var createGithubTool = createTool;
|
|
24
28
|
function isPlainObject(value) {
|
|
25
29
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -140,6 +144,36 @@ function getPrLabel(subscription, snapshot) {
|
|
|
140
144
|
function getMergedNotificationSummary(label) {
|
|
141
145
|
return `${label} was merged. This thread has been automatically unsubscribed from this PR. Resubscribe if you still need updates.`;
|
|
142
146
|
}
|
|
147
|
+
function getCommentExcerpt(body) {
|
|
148
|
+
const excerpt = body.replace(/\s+/g, " ").trim();
|
|
149
|
+
return excerpt.length > 240 ? `${excerpt.slice(0, 237)}...` : excerpt;
|
|
150
|
+
}
|
|
151
|
+
function getCommentNotificationSummary(pr, snapshot) {
|
|
152
|
+
if (!snapshot.latestCommentAuthor || !snapshot.latestCommentBody) return void 0;
|
|
153
|
+
return `${snapshot.latestCommentAuthor} commented on ${pr}: ${getCommentExcerpt(snapshot.latestCommentBody)}`;
|
|
154
|
+
}
|
|
155
|
+
var githubActivityNotificationPriority = {
|
|
156
|
+
high: 0,
|
|
157
|
+
medium: 1
|
|
158
|
+
};
|
|
159
|
+
function getGithubActivityNotificationRank(notification) {
|
|
160
|
+
return notification.kind === "pull-request-activity" ? 0 : 1;
|
|
161
|
+
}
|
|
162
|
+
function compareGithubActivityNotifications(a, b) {
|
|
163
|
+
if (!a && !b) return 0;
|
|
164
|
+
if (!a) return 1;
|
|
165
|
+
if (!b) return -1;
|
|
166
|
+
const priorityComparison = githubActivityNotificationPriority[a.priority] - githubActivityNotificationPriority[b.priority];
|
|
167
|
+
if (priorityComparison !== 0) return priorityComparison;
|
|
168
|
+
return getGithubActivityNotificationRank(a) - getGithubActivityNotificationRank(b);
|
|
169
|
+
}
|
|
170
|
+
function classifyGithubCommentActivityNotification(input) {
|
|
171
|
+
if (isBotOnlyActivity(input.snapshot)) return void 0;
|
|
172
|
+
const pr = `${input.subscription.owner}/${input.subscription.repo}#${input.subscription.number}`;
|
|
173
|
+
const summary = getCommentNotificationSummary(pr, input.snapshot);
|
|
174
|
+
if (!summary) return void 0;
|
|
175
|
+
return { kind: "pull-request-activity", priority: "high", summary };
|
|
176
|
+
}
|
|
143
177
|
function getCheckUpdatedTime(check) {
|
|
144
178
|
const value = check.updatedAt ? Date.parse(check.updatedAt) : Number.NaN;
|
|
145
179
|
return Number.isFinite(value) ? value : 0;
|
|
@@ -263,10 +297,11 @@ function classifyGithubActivityNotification(input) {
|
|
|
263
297
|
}
|
|
264
298
|
if (input.snapshot.ciState === "pending" && input.subscription.lastObservedCiState === "pending") return void 0;
|
|
265
299
|
if (isBotOnlyActivity(input.snapshot)) return void 0;
|
|
300
|
+
const commentSummary = getCommentNotificationSummary(pr, input.snapshot);
|
|
266
301
|
return {
|
|
267
302
|
kind: "pull-request-activity",
|
|
268
|
-
priority: "medium",
|
|
269
|
-
summary: `${pr} has new activity${input.snapshot.title ? `: ${input.snapshot.title}` : ""}`
|
|
303
|
+
priority: commentSummary ? "high" : "medium",
|
|
304
|
+
summary: commentSummary ?? `${pr} has new activity${input.snapshot.title ? `: ${input.snapshot.title}` : ""}`
|
|
270
305
|
};
|
|
271
306
|
}
|
|
272
307
|
function classifyGithubBaselineNotification(input) {
|
|
@@ -391,13 +426,15 @@ var GitcrawlSyncClient = class {
|
|
|
391
426
|
join threads t on t.id=rt.thread_id
|
|
392
427
|
join repositories r on r.id=t.repo_id
|
|
393
428
|
where r.owner=${owner} and r.name=${repo} and t.number=${number} and rt.is_resolved=0`);
|
|
394
|
-
const
|
|
429
|
+
const latestComments = await queryGitcrawlDb(`select c.author_login, c.author_type, c.is_bot, c.body, json_extract(c.raw_json, '$.html_url') as html_url,
|
|
430
|
+
coalesce(c.updated_at_gh, c.created_at_gh) as updated_at
|
|
395
431
|
from comments c
|
|
396
432
|
join threads t on t.id=c.thread_id
|
|
397
433
|
join repositories r on r.id=t.repo_id
|
|
398
434
|
where r.owner=${owner} and r.name=${repo} and t.number=${number}
|
|
399
435
|
order by coalesce(c.updated_at_gh, c.created_at_gh) desc
|
|
400
|
-
limit
|
|
436
|
+
limit 20`);
|
|
437
|
+
const latestComment = latestComments[0];
|
|
401
438
|
const checks = normalizeGithubChecksForSnapshot({
|
|
402
439
|
checkRows: checkRows.map((row) => ({
|
|
403
440
|
source: "check",
|
|
@@ -459,7 +496,18 @@ var GitcrawlSyncClient = class {
|
|
|
459
496
|
latestReviewThreadAt: readString(reviewState?.latest_review_thread_at),
|
|
460
497
|
latestCommentAuthor: readString(latestComment?.author_login),
|
|
461
498
|
latestCommentAuthorType: readString(latestComment?.author_type),
|
|
462
|
-
latestCommentIsBot: latestComment?.is_bot === 1
|
|
499
|
+
latestCommentIsBot: latestComment?.is_bot === 1,
|
|
500
|
+
latestCommentBody: readString(latestComment?.body),
|
|
501
|
+
latestCommentUrl: readString(latestComment?.html_url),
|
|
502
|
+
latestCommentUpdatedAt: readString(latestComment?.updated_at),
|
|
503
|
+
latestComments: latestComments.map((comment) => ({
|
|
504
|
+
author: readString(comment.author_login),
|
|
505
|
+
authorType: readString(comment.author_type),
|
|
506
|
+
isBot: comment.is_bot === 1,
|
|
507
|
+
body: readString(comment.body),
|
|
508
|
+
url: readString(comment.html_url),
|
|
509
|
+
updatedAt: readString(comment.updated_at)
|
|
510
|
+
}))
|
|
463
511
|
};
|
|
464
512
|
} catch {
|
|
465
513
|
return void 0;
|
|
@@ -514,9 +562,11 @@ var GithubSignals = class extends SignalProvider {
|
|
|
514
562
|
#syncClient;
|
|
515
563
|
#repositoryResolver;
|
|
516
564
|
#polling = /* @__PURE__ */ new Map();
|
|
565
|
+
#permissionCache = /* @__PURE__ */ new Map();
|
|
517
566
|
#agent;
|
|
518
567
|
#agentOptions = {};
|
|
519
568
|
#subscriptionsChangedHandler;
|
|
569
|
+
#pollingChangedHandler;
|
|
520
570
|
constructor(options = {}) {
|
|
521
571
|
super();
|
|
522
572
|
this.#options = options;
|
|
@@ -551,6 +601,9 @@ var GithubSignals = class extends SignalProvider {
|
|
|
551
601
|
onSubscriptionsChanged(handler) {
|
|
552
602
|
this.#subscriptionsChangedHandler = handler;
|
|
553
603
|
}
|
|
604
|
+
onPollingChanged(handler) {
|
|
605
|
+
this.#pollingChangedHandler = handler;
|
|
606
|
+
}
|
|
554
607
|
__registerMastra(mastra) {
|
|
555
608
|
super.__registerMastra(mastra);
|
|
556
609
|
this.#ghMastra = mastra;
|
|
@@ -589,15 +642,13 @@ var GithubSignals = class extends SignalProvider {
|
|
|
589
642
|
this.#polling.delete(pollingKey);
|
|
590
643
|
}
|
|
591
644
|
if (this.#polling.has(key)) return true;
|
|
592
|
-
let scheduledPollCount = options.pollImmediately ? 1 : 0;
|
|
593
645
|
const runPoll = (pollOptions = {}) => {
|
|
594
646
|
void this.#pollThread(input, pollOptions).catch((error) => {
|
|
595
647
|
console.warn("GitHub PR polling failed:", error);
|
|
596
648
|
});
|
|
597
649
|
};
|
|
598
650
|
const timer = setInterval(() => {
|
|
599
|
-
|
|
600
|
-
runPoll({ includeComments: scheduledPollCount % 2 === 1 });
|
|
651
|
+
runPoll({ includeComments: true });
|
|
601
652
|
}, this.#options.pollIntervalMs ?? 3e5);
|
|
602
653
|
if (options.pollImmediately) runPoll({ includeComments: true });
|
|
603
654
|
timer.unref?.();
|
|
@@ -614,6 +665,9 @@ var GithubSignals = class extends SignalProvider {
|
|
|
614
665
|
isPollingThread(input) {
|
|
615
666
|
return this.#polling.has(this.#pollingKey(input));
|
|
616
667
|
}
|
|
668
|
+
isPollingThreadRunning(input) {
|
|
669
|
+
return this.#polling.get(this.#pollingKey(input))?.running ?? false;
|
|
670
|
+
}
|
|
617
671
|
getPollIntervalMs() {
|
|
618
672
|
return this.#options.pollIntervalMs ?? 3e5;
|
|
619
673
|
}
|
|
@@ -799,6 +853,9 @@ var GithubSignals = class extends SignalProvider {
|
|
|
799
853
|
#notifySubscriptionsChanged(input) {
|
|
800
854
|
this.#subscriptionsChangedHandler?.(input);
|
|
801
855
|
}
|
|
856
|
+
#notifyPollingChanged(input) {
|
|
857
|
+
this.#pollingChangedHandler?.(input);
|
|
858
|
+
}
|
|
802
859
|
async #pollThread(input, options = {}) {
|
|
803
860
|
const key = this.#pollingKey(input);
|
|
804
861
|
const state = this.#polling.get(key);
|
|
@@ -806,6 +863,7 @@ var GithubSignals = class extends SignalProvider {
|
|
|
806
863
|
return 0;
|
|
807
864
|
}
|
|
808
865
|
if (state) state.running = true;
|
|
866
|
+
this.#notifyPollingChanged({ threadId: input.threadId, resourceId: input.resourceId, running: true });
|
|
809
867
|
try {
|
|
810
868
|
const { threadStore, loadedThread } = await this.#loadThread(input);
|
|
811
869
|
const githubMetadata = getGithubMetadata(loadedThread.metadata);
|
|
@@ -824,7 +882,9 @@ var GithubSignals = class extends SignalProvider {
|
|
|
824
882
|
includeComments: options.includeComments
|
|
825
883
|
};
|
|
826
884
|
const syncResult = await this.#syncClient.syncPullRequest(syncInput);
|
|
827
|
-
|
|
885
|
+
let snapshot = syncResult.ok ? await this.#syncClient.getPullRequestSnapshot?.(syncInput) : void 0;
|
|
886
|
+
if (snapshot)
|
|
887
|
+
snapshot = await this.#filterUnauthorizedLatestComment(subscription.owner, subscription.repo, snapshot);
|
|
828
888
|
const nextSubscription = {
|
|
829
889
|
...subscription,
|
|
830
890
|
updatedAt: now,
|
|
@@ -837,25 +897,28 @@ var GithubSignals = class extends SignalProvider {
|
|
|
837
897
|
const previousContentHash = subscription.lastObservedContentHash;
|
|
838
898
|
const previousThreadContentHash = subscription.lastObservedThreadContentHash;
|
|
839
899
|
const previousHeadSha = subscription.lastObservedHeadSha;
|
|
900
|
+
const latestCommentChanged = !!previousGithubUpdatedAt && !!snapshot?.latestCommentUpdatedAt && Date.parse(snapshot.latestCommentUpdatedAt) > Date.parse(previousGithubUpdatedAt);
|
|
840
901
|
if (snapshot) applySnapshotCursor(nextSubscription, snapshot);
|
|
841
902
|
const isFirstObservation = syncResult.ok && snapshot && !previousGithubUpdatedAt && !previousContentHash;
|
|
842
903
|
const legacyAggregateChanged = previousContentHash && snapshot?.contentHash && previousContentHash !== snapshot.contentHash && !previousThreadContentHash && !previousHeadSha;
|
|
843
|
-
const changed = isFirstObservation || syncResult.ok && snapshot && (legacyAggregateChanged || previousThreadContentHash && snapshot.threadContentHash && previousThreadContentHash !== snapshot.threadContentHash || previousHeadSha && snapshot.headSha && previousHeadSha !== snapshot.headSha || subscription.lastObservedState && snapshot.state && subscription.lastObservedState !== snapshot.state || subscription.lastObservedMergeableState && snapshot.mergeableState && subscription.lastObservedMergeableState !== snapshot.mergeableState || subscription.lastObservedCiState && snapshot.ciState && subscription.lastObservedCiState !== snapshot.ciState || subscription.lastObservedReviewStateHash && snapshot.reviewStateHash && subscription.lastObservedReviewStateHash !== snapshot.reviewStateHash);
|
|
904
|
+
const changed = isFirstObservation || syncResult.ok && snapshot && (legacyAggregateChanged || latestCommentChanged || previousThreadContentHash && snapshot.threadContentHash && previousThreadContentHash !== snapshot.threadContentHash || previousHeadSha && snapshot.headSha && previousHeadSha !== snapshot.headSha || subscription.lastObservedState && snapshot.state && subscription.lastObservedState !== snapshot.state || subscription.lastObservedMergeableState && snapshot.mergeableState && subscription.lastObservedMergeableState !== snapshot.mergeableState || subscription.lastObservedCiState && snapshot.ciState && subscription.lastObservedCiState !== snapshot.ciState || subscription.lastObservedReviewStateHash && snapshot.reviewStateHash && subscription.lastObservedReviewStateHash !== snapshot.reviewStateHash);
|
|
844
905
|
let shouldKeepSubscription = true;
|
|
845
|
-
if (changed) {
|
|
846
|
-
const
|
|
906
|
+
if (changed && snapshot) {
|
|
907
|
+
const notifications = await this.#sendActivityNotifications({
|
|
847
908
|
polling: input,
|
|
848
909
|
subscription,
|
|
849
910
|
snapshot,
|
|
850
911
|
previousGithubUpdatedAt,
|
|
851
|
-
previousContentHash
|
|
912
|
+
previousContentHash,
|
|
913
|
+
latestCommentChanged
|
|
852
914
|
});
|
|
853
|
-
|
|
915
|
+
const primaryNotification = notifications[0];
|
|
916
|
+
if (primaryNotification) {
|
|
854
917
|
nextSubscription.lastNotificationAt = now;
|
|
855
|
-
nextSubscription.lastNotificationKind =
|
|
856
|
-
nextSubscription.lastNotificationPriority =
|
|
857
|
-
nextSubscription.lastNotificationSummary =
|
|
858
|
-
shouldKeepSubscription = notification.kind !== "pull-request-merged";
|
|
918
|
+
nextSubscription.lastNotificationKind = primaryNotification.kind;
|
|
919
|
+
nextSubscription.lastNotificationPriority = primaryNotification.priority;
|
|
920
|
+
nextSubscription.lastNotificationSummary = primaryNotification.summary;
|
|
921
|
+
shouldKeepSubscription = notifications.every((notification) => notification.kind !== "pull-request-merged");
|
|
859
922
|
}
|
|
860
923
|
}
|
|
861
924
|
if (shouldKeepSubscription) subscriptions.push(nextSubscription);
|
|
@@ -878,17 +941,20 @@ var GithubSignals = class extends SignalProvider {
|
|
|
878
941
|
} finally {
|
|
879
942
|
const latestState = this.#polling.get(key);
|
|
880
943
|
if (latestState) latestState.running = false;
|
|
944
|
+
this.#notifyPollingChanged({ threadId: input.threadId, resourceId: input.resourceId, running: false });
|
|
881
945
|
}
|
|
882
946
|
}
|
|
883
|
-
|
|
947
|
+
#createGithubNotificationInput(input) {
|
|
884
948
|
const failingChecks = getFailingChecks(input.snapshot);
|
|
885
949
|
const pendingChecks = getPendingChecks(input.snapshot);
|
|
950
|
+
const latestCommentExcerpt = input.snapshot.latestCommentBody ? getCommentExcerpt(input.snapshot.latestCommentBody) : void 0;
|
|
951
|
+
const latestCommentDedupeSuffix = input.notification.kind === "pull-request-activity" && input.snapshot.latestCommentUrl ? `comment:${input.snapshot.latestCommentUrl}:${input.snapshot.latestCommentUpdatedAt ?? ""}` : input.dedupeSuffix;
|
|
886
952
|
const notificationInput = {
|
|
887
953
|
source: "github",
|
|
888
954
|
kind: input.notification.kind,
|
|
889
955
|
priority: input.notification.priority,
|
|
890
956
|
summary: input.notification.summary,
|
|
891
|
-
dedupeKey: `github:${input.subscription.owner}/${input.subscription.repo}#${input.subscription.number}:${
|
|
957
|
+
dedupeKey: `github:${input.subscription.owner}/${input.subscription.repo}#${input.subscription.number}:${latestCommentDedupeSuffix}`,
|
|
892
958
|
coalesceKey: `github:${input.subscription.owner}/${input.subscription.repo}#${input.subscription.number}:${input.notification.kind}`,
|
|
893
959
|
attributes: {
|
|
894
960
|
owner: input.subscription.owner,
|
|
@@ -902,6 +968,10 @@ var GithubSignals = class extends SignalProvider {
|
|
|
902
968
|
...input.snapshot.mergeableState ? { mergeableState: input.snapshot.mergeableState } : {},
|
|
903
969
|
...input.snapshot.ciState ? { ciState: input.snapshot.ciState } : {},
|
|
904
970
|
...input.snapshot.unresolvedReviewThreads !== void 0 ? { unresolvedReviewThreads: input.snapshot.unresolvedReviewThreads } : {},
|
|
971
|
+
...input.snapshot.latestCommentAuthor ? { latestCommentAuthor: input.snapshot.latestCommentAuthor } : {},
|
|
972
|
+
...latestCommentExcerpt ? { latestCommentExcerpt } : {},
|
|
973
|
+
...input.snapshot.latestCommentUrl ? { latestCommentUrl: input.snapshot.latestCommentUrl } : {},
|
|
974
|
+
...input.snapshot.latestCommentUpdatedAt ? { latestCommentUpdatedAt: input.snapshot.latestCommentUpdatedAt } : {},
|
|
905
975
|
...failingChecks.length > 0 ? { failingChecks: failingChecks.map((check) => check.name).join(", ") } : {},
|
|
906
976
|
...pendingChecks.length > 0 ? { pendingChecks: pendingChecks.map((check) => check.name).join(", ") } : {}
|
|
907
977
|
},
|
|
@@ -930,11 +1000,19 @@ var GithubSignals = class extends SignalProvider {
|
|
|
930
1000
|
latestCommentAuthor: input.snapshot.latestCommentAuthor,
|
|
931
1001
|
latestCommentAuthorType: input.snapshot.latestCommentAuthorType,
|
|
932
1002
|
latestCommentIsBot: input.snapshot.latestCommentIsBot,
|
|
1003
|
+
latestCommentBody: input.snapshot.latestCommentBody,
|
|
1004
|
+
latestCommentExcerpt,
|
|
1005
|
+
latestCommentUrl: input.snapshot.latestCommentUrl,
|
|
1006
|
+
latestCommentUpdatedAt: input.snapshot.latestCommentUpdatedAt,
|
|
933
1007
|
failingChecks,
|
|
934
1008
|
pendingChecks
|
|
935
1009
|
}
|
|
936
1010
|
}
|
|
937
1011
|
};
|
|
1012
|
+
return notificationInput;
|
|
1013
|
+
}
|
|
1014
|
+
async #sendGithubNotification(input) {
|
|
1015
|
+
const notificationInput = this.#createGithubNotificationInput(input);
|
|
938
1016
|
const streamOptions = await this.#agentOptions.getNotificationStreamOptions?.(input.target);
|
|
939
1017
|
await input.agent?.sendNotificationSignal?.(
|
|
940
1018
|
notificationInput,
|
|
@@ -953,25 +1031,144 @@ var GithubSignals = class extends SignalProvider {
|
|
|
953
1031
|
dedupeSuffix: `baseline:${input.subscription.lastSubscribeSignalId}`
|
|
954
1032
|
});
|
|
955
1033
|
}
|
|
956
|
-
async #
|
|
1034
|
+
async #isAuthorizedAuthor(owner, repo, user, metadata = {}) {
|
|
1035
|
+
if (!user) return false;
|
|
1036
|
+
const normalizedUser = user.toLowerCase();
|
|
1037
|
+
const isBot = metadata.isBot === true || metadata.authorType?.toLowerCase() === "bot" || normalizedUser.endsWith("[bot]");
|
|
1038
|
+
if (isBot) {
|
|
1039
|
+
const ignoredBots = this.#options.ignoredBots ?? [];
|
|
1040
|
+
if (ignoredBots.some((bot) => bot.toLowerCase() === normalizedUser)) return false;
|
|
1041
|
+
const authorizedBots = this.#options.authorizedBots ?? DEFAULT_AUTHORIZED_BOTS;
|
|
1042
|
+
return authorizedBots.some((bot) => bot.toLowerCase() === normalizedUser);
|
|
1043
|
+
}
|
|
1044
|
+
const permission = await this.#loadAuthorPermission(owner, repo, user);
|
|
1045
|
+
const authorizedPermissions = this.#options.authorizedPermissions ?? DEFAULT_AUTHORIZED_PERMISSIONS;
|
|
1046
|
+
return !!permission && authorizedPermissions.includes(permission);
|
|
1047
|
+
}
|
|
1048
|
+
async #filterUnauthorizedLatestComment(owner, repo, snapshot) {
|
|
1049
|
+
const comments = snapshot.latestComments?.length ? snapshot.latestComments : [
|
|
1050
|
+
{
|
|
1051
|
+
author: snapshot.latestCommentAuthor,
|
|
1052
|
+
authorType: snapshot.latestCommentAuthorType,
|
|
1053
|
+
isBot: snapshot.latestCommentIsBot,
|
|
1054
|
+
body: snapshot.latestCommentBody,
|
|
1055
|
+
url: snapshot.latestCommentUrl,
|
|
1056
|
+
updatedAt: snapshot.latestCommentUpdatedAt
|
|
1057
|
+
}
|
|
1058
|
+
];
|
|
1059
|
+
if (!comments.some((comment) => comment.author)) return snapshot;
|
|
1060
|
+
if (!comments.some((comment) => comment.body || comment.url || comment.updatedAt)) return snapshot;
|
|
1061
|
+
for (const comment of comments) {
|
|
1062
|
+
if (!await this.#isAuthorizedAuthor(owner, repo, comment.author, {
|
|
1063
|
+
authorType: comment.authorType,
|
|
1064
|
+
isBot: comment.isBot
|
|
1065
|
+
})) {
|
|
1066
|
+
continue;
|
|
1067
|
+
}
|
|
1068
|
+
return {
|
|
1069
|
+
...snapshot,
|
|
1070
|
+
latestCommentAuthor: comment.author,
|
|
1071
|
+
latestCommentAuthorType: comment.authorType,
|
|
1072
|
+
latestCommentIsBot: comment.isBot,
|
|
1073
|
+
latestCommentBody: comment.body,
|
|
1074
|
+
latestCommentUrl: comment.url,
|
|
1075
|
+
latestCommentUpdatedAt: comment.updatedAt
|
|
1076
|
+
};
|
|
1077
|
+
}
|
|
1078
|
+
return {
|
|
1079
|
+
...snapshot,
|
|
1080
|
+
latestCommentAuthor: void 0,
|
|
1081
|
+
latestCommentAuthorType: void 0,
|
|
1082
|
+
latestCommentIsBot: void 0,
|
|
1083
|
+
latestCommentBody: void 0,
|
|
1084
|
+
latestCommentUrl: void 0,
|
|
1085
|
+
latestCommentUpdatedAt: void 0
|
|
1086
|
+
};
|
|
1087
|
+
}
|
|
1088
|
+
async #loadAuthorPermission(owner, repo, user) {
|
|
1089
|
+
const cacheKey = `${owner}/${repo}:${user.toLowerCase()}`;
|
|
1090
|
+
const cached = this.#permissionCache.get(cacheKey);
|
|
1091
|
+
if (cached && cached.expiresAt > Date.now()) return cached.permission;
|
|
1092
|
+
if (cached) this.#permissionCache.delete(cacheKey);
|
|
1093
|
+
try {
|
|
1094
|
+
let permission;
|
|
1095
|
+
if (this.#options.permissionResolver) {
|
|
1096
|
+
permission = await this.#options.permissionResolver.getPermission(owner, repo, user);
|
|
1097
|
+
} else {
|
|
1098
|
+
const { stdout } = await execFileAsync("gh", [
|
|
1099
|
+
"api",
|
|
1100
|
+
`repos/${owner}/${repo}/collaborators/${user}/permission`,
|
|
1101
|
+
"--jq",
|
|
1102
|
+
".permission"
|
|
1103
|
+
]);
|
|
1104
|
+
const raw = stdout.trim();
|
|
1105
|
+
permission = ["admin", "maintain", "write", "triage", "read", "none"].includes(
|
|
1106
|
+
raw
|
|
1107
|
+
) ? raw : void 0;
|
|
1108
|
+
}
|
|
1109
|
+
if (permission) {
|
|
1110
|
+
this.#permissionCache.set(cacheKey, { permission, expiresAt: Date.now() + PERMISSION_CACHE_TTL_MS });
|
|
1111
|
+
}
|
|
1112
|
+
return permission;
|
|
1113
|
+
} catch {
|
|
1114
|
+
this.#permissionCache.delete(cacheKey);
|
|
1115
|
+
return void 0;
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
async #sendActivityNotifications(input) {
|
|
957
1119
|
const agent = this.#getNotificationAgent(input.polling);
|
|
958
|
-
if (!agent?.sendNotificationSignal) return
|
|
959
|
-
const
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
1120
|
+
if (!agent?.sendNotificationSignal) return [];
|
|
1121
|
+
const notifications = [
|
|
1122
|
+
classifyGithubActivityNotification({
|
|
1123
|
+
subscription: input.subscription,
|
|
1124
|
+
snapshot: input.snapshot
|
|
1125
|
+
})
|
|
1126
|
+
];
|
|
1127
|
+
if (input.latestCommentChanged && notifications[0]?.kind !== "pull-request-activity") {
|
|
1128
|
+
notifications.push(
|
|
1129
|
+
classifyGithubCommentActivityNotification({
|
|
1130
|
+
subscription: input.subscription,
|
|
1131
|
+
snapshot: input.snapshot
|
|
1132
|
+
})
|
|
1133
|
+
);
|
|
1134
|
+
}
|
|
1135
|
+
const sent = [];
|
|
1136
|
+
const notificationInputs = [];
|
|
1137
|
+
for (const notification of notifications.sort(compareGithubActivityNotifications)) {
|
|
1138
|
+
if (!notification) continue;
|
|
1139
|
+
if (AUTHOR_GATED_NOTIFICATION_KINDS.has(notification.kind)) {
|
|
1140
|
+
const authorized = await this.#isAuthorizedAuthor(
|
|
1141
|
+
input.subscription.owner,
|
|
1142
|
+
input.subscription.repo,
|
|
1143
|
+
input.snapshot.latestCommentAuthor,
|
|
1144
|
+
{
|
|
1145
|
+
authorType: input.snapshot.latestCommentAuthorType,
|
|
1146
|
+
isBot: input.snapshot.latestCommentIsBot
|
|
1147
|
+
}
|
|
1148
|
+
);
|
|
1149
|
+
if (!authorized) continue;
|
|
1150
|
+
}
|
|
1151
|
+
notificationInputs.push(
|
|
1152
|
+
this.#createGithubNotificationInput({
|
|
1153
|
+
subscription: input.subscription,
|
|
1154
|
+
snapshot: input.snapshot,
|
|
1155
|
+
notification,
|
|
1156
|
+
dedupeSuffix: input.snapshot.contentHash ?? input.snapshot.githubUpdatedAt ?? String(Date.now()),
|
|
1157
|
+
previousGithubUpdatedAt: input.previousGithubUpdatedAt,
|
|
1158
|
+
previousContentHash: input.previousContentHash
|
|
1159
|
+
})
|
|
1160
|
+
);
|
|
1161
|
+
sent.push(notification);
|
|
1162
|
+
}
|
|
1163
|
+
if (notificationInputs.length > 0) {
|
|
1164
|
+
const target = { resourceId: input.polling.resourceId, threadId: input.polling.threadId };
|
|
1165
|
+
const streamOptions = await this.#agentOptions.getNotificationStreamOptions?.(target);
|
|
1166
|
+
await agent.sendNotificationSignal(
|
|
1167
|
+
notificationInputs,
|
|
1168
|
+
streamOptions ? { ...target, ifIdle: { streamOptions } } : target
|
|
1169
|
+
);
|
|
1170
|
+
}
|
|
1171
|
+
return sent;
|
|
975
1172
|
}
|
|
976
1173
|
async #subscribe(input) {
|
|
977
1174
|
const { owner, repo } = await this.#resolveRepository(input);
|