@mastra/github-signals 0.1.0 → 0.1.1
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 +31 -0
- package/dist/index.cjs +247 -44
- 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 +247 -44
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
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
|
}
|
|
@@ -705,6 +759,10 @@ var GithubSignals = class extends SignalProvider {
|
|
|
705
759
|
}
|
|
706
760
|
#createTools(args) {
|
|
707
761
|
const threadContext = this.#getThreadContext(args);
|
|
762
|
+
const getExecutionThreadContext = (context) => ({
|
|
763
|
+
threadId: context?.agent?.threadId ?? threadContext.threadId,
|
|
764
|
+
resourceId: context?.agent?.resourceId ?? threadContext.resourceId
|
|
765
|
+
});
|
|
708
766
|
return {
|
|
709
767
|
...args.tools,
|
|
710
768
|
github_subscribe_pr: createGithubTool({
|
|
@@ -715,14 +773,15 @@ var GithubSignals = class extends SignalProvider {
|
|
|
715
773
|
owner: z.string().optional(),
|
|
716
774
|
repo: z.string().optional()
|
|
717
775
|
}),
|
|
718
|
-
execute: async (input) => {
|
|
776
|
+
execute: async (input, context) => {
|
|
777
|
+
const executionThreadContext = getExecutionThreadContext(context);
|
|
719
778
|
const result = await this.#subscribe({
|
|
720
779
|
id: `github-tool-subscribe-${randomUUID()}`,
|
|
721
780
|
owner: input.owner,
|
|
722
781
|
repo: input.repo,
|
|
723
782
|
number: input.number,
|
|
724
|
-
threadId:
|
|
725
|
-
resourceId:
|
|
783
|
+
threadId: executionThreadContext.threadId,
|
|
784
|
+
resourceId: executionThreadContext.resourceId
|
|
726
785
|
});
|
|
727
786
|
return {
|
|
728
787
|
subscribed: true,
|
|
@@ -742,14 +801,15 @@ var GithubSignals = class extends SignalProvider {
|
|
|
742
801
|
owner: z.string().optional(),
|
|
743
802
|
repo: z.string().optional()
|
|
744
803
|
}),
|
|
745
|
-
execute: async (input) => {
|
|
804
|
+
execute: async (input, context) => {
|
|
805
|
+
const executionThreadContext = getExecutionThreadContext(context);
|
|
746
806
|
const result = await this.#unsubscribe({
|
|
747
807
|
id: `github-tool-unsubscribe-${randomUUID()}`,
|
|
748
808
|
owner: input.owner,
|
|
749
809
|
repo: input.repo,
|
|
750
810
|
number: input.number,
|
|
751
|
-
threadId:
|
|
752
|
-
resourceId:
|
|
811
|
+
threadId: executionThreadContext.threadId,
|
|
812
|
+
resourceId: executionThreadContext.resourceId
|
|
753
813
|
});
|
|
754
814
|
return {
|
|
755
815
|
unsubscribed: result.removed ?? false,
|
|
@@ -799,6 +859,9 @@ var GithubSignals = class extends SignalProvider {
|
|
|
799
859
|
#notifySubscriptionsChanged(input) {
|
|
800
860
|
this.#subscriptionsChangedHandler?.(input);
|
|
801
861
|
}
|
|
862
|
+
#notifyPollingChanged(input) {
|
|
863
|
+
this.#pollingChangedHandler?.(input);
|
|
864
|
+
}
|
|
802
865
|
async #pollThread(input, options = {}) {
|
|
803
866
|
const key = this.#pollingKey(input);
|
|
804
867
|
const state = this.#polling.get(key);
|
|
@@ -806,6 +869,7 @@ var GithubSignals = class extends SignalProvider {
|
|
|
806
869
|
return 0;
|
|
807
870
|
}
|
|
808
871
|
if (state) state.running = true;
|
|
872
|
+
this.#notifyPollingChanged({ threadId: input.threadId, resourceId: input.resourceId, running: true });
|
|
809
873
|
try {
|
|
810
874
|
const { threadStore, loadedThread } = await this.#loadThread(input);
|
|
811
875
|
const githubMetadata = getGithubMetadata(loadedThread.metadata);
|
|
@@ -824,7 +888,9 @@ var GithubSignals = class extends SignalProvider {
|
|
|
824
888
|
includeComments: options.includeComments
|
|
825
889
|
};
|
|
826
890
|
const syncResult = await this.#syncClient.syncPullRequest(syncInput);
|
|
827
|
-
|
|
891
|
+
let snapshot = syncResult.ok ? await this.#syncClient.getPullRequestSnapshot?.(syncInput) : void 0;
|
|
892
|
+
if (snapshot)
|
|
893
|
+
snapshot = await this.#filterUnauthorizedLatestComment(subscription.owner, subscription.repo, snapshot);
|
|
828
894
|
const nextSubscription = {
|
|
829
895
|
...subscription,
|
|
830
896
|
updatedAt: now,
|
|
@@ -837,25 +903,28 @@ var GithubSignals = class extends SignalProvider {
|
|
|
837
903
|
const previousContentHash = subscription.lastObservedContentHash;
|
|
838
904
|
const previousThreadContentHash = subscription.lastObservedThreadContentHash;
|
|
839
905
|
const previousHeadSha = subscription.lastObservedHeadSha;
|
|
906
|
+
const latestCommentChanged = !!previousGithubUpdatedAt && !!snapshot?.latestCommentUpdatedAt && Date.parse(snapshot.latestCommentUpdatedAt) > Date.parse(previousGithubUpdatedAt);
|
|
840
907
|
if (snapshot) applySnapshotCursor(nextSubscription, snapshot);
|
|
841
908
|
const isFirstObservation = syncResult.ok && snapshot && !previousGithubUpdatedAt && !previousContentHash;
|
|
842
909
|
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);
|
|
910
|
+
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
911
|
let shouldKeepSubscription = true;
|
|
845
|
-
if (changed) {
|
|
846
|
-
const
|
|
912
|
+
if (changed && snapshot) {
|
|
913
|
+
const notifications = await this.#sendActivityNotifications({
|
|
847
914
|
polling: input,
|
|
848
915
|
subscription,
|
|
849
916
|
snapshot,
|
|
850
917
|
previousGithubUpdatedAt,
|
|
851
|
-
previousContentHash
|
|
918
|
+
previousContentHash,
|
|
919
|
+
latestCommentChanged
|
|
852
920
|
});
|
|
853
|
-
|
|
921
|
+
const primaryNotification = notifications[0];
|
|
922
|
+
if (primaryNotification) {
|
|
854
923
|
nextSubscription.lastNotificationAt = now;
|
|
855
|
-
nextSubscription.lastNotificationKind =
|
|
856
|
-
nextSubscription.lastNotificationPriority =
|
|
857
|
-
nextSubscription.lastNotificationSummary =
|
|
858
|
-
shouldKeepSubscription = notification.kind !== "pull-request-merged";
|
|
924
|
+
nextSubscription.lastNotificationKind = primaryNotification.kind;
|
|
925
|
+
nextSubscription.lastNotificationPriority = primaryNotification.priority;
|
|
926
|
+
nextSubscription.lastNotificationSummary = primaryNotification.summary;
|
|
927
|
+
shouldKeepSubscription = notifications.every((notification) => notification.kind !== "pull-request-merged");
|
|
859
928
|
}
|
|
860
929
|
}
|
|
861
930
|
if (shouldKeepSubscription) subscriptions.push(nextSubscription);
|
|
@@ -878,17 +947,20 @@ var GithubSignals = class extends SignalProvider {
|
|
|
878
947
|
} finally {
|
|
879
948
|
const latestState = this.#polling.get(key);
|
|
880
949
|
if (latestState) latestState.running = false;
|
|
950
|
+
this.#notifyPollingChanged({ threadId: input.threadId, resourceId: input.resourceId, running: false });
|
|
881
951
|
}
|
|
882
952
|
}
|
|
883
|
-
|
|
953
|
+
#createGithubNotificationInput(input) {
|
|
884
954
|
const failingChecks = getFailingChecks(input.snapshot);
|
|
885
955
|
const pendingChecks = getPendingChecks(input.snapshot);
|
|
956
|
+
const latestCommentExcerpt = input.snapshot.latestCommentBody ? getCommentExcerpt(input.snapshot.latestCommentBody) : void 0;
|
|
957
|
+
const latestCommentDedupeSuffix = input.notification.kind === "pull-request-activity" && input.snapshot.latestCommentUrl ? `comment:${input.snapshot.latestCommentUrl}:${input.snapshot.latestCommentUpdatedAt ?? ""}` : input.dedupeSuffix;
|
|
886
958
|
const notificationInput = {
|
|
887
959
|
source: "github",
|
|
888
960
|
kind: input.notification.kind,
|
|
889
961
|
priority: input.notification.priority,
|
|
890
962
|
summary: input.notification.summary,
|
|
891
|
-
dedupeKey: `github:${input.subscription.owner}/${input.subscription.repo}#${input.subscription.number}:${
|
|
963
|
+
dedupeKey: `github:${input.subscription.owner}/${input.subscription.repo}#${input.subscription.number}:${latestCommentDedupeSuffix}`,
|
|
892
964
|
coalesceKey: `github:${input.subscription.owner}/${input.subscription.repo}#${input.subscription.number}:${input.notification.kind}`,
|
|
893
965
|
attributes: {
|
|
894
966
|
owner: input.subscription.owner,
|
|
@@ -902,6 +974,10 @@ var GithubSignals = class extends SignalProvider {
|
|
|
902
974
|
...input.snapshot.mergeableState ? { mergeableState: input.snapshot.mergeableState } : {},
|
|
903
975
|
...input.snapshot.ciState ? { ciState: input.snapshot.ciState } : {},
|
|
904
976
|
...input.snapshot.unresolvedReviewThreads !== void 0 ? { unresolvedReviewThreads: input.snapshot.unresolvedReviewThreads } : {},
|
|
977
|
+
...input.snapshot.latestCommentAuthor ? { latestCommentAuthor: input.snapshot.latestCommentAuthor } : {},
|
|
978
|
+
...latestCommentExcerpt ? { latestCommentExcerpt } : {},
|
|
979
|
+
...input.snapshot.latestCommentUrl ? { latestCommentUrl: input.snapshot.latestCommentUrl } : {},
|
|
980
|
+
...input.snapshot.latestCommentUpdatedAt ? { latestCommentUpdatedAt: input.snapshot.latestCommentUpdatedAt } : {},
|
|
905
981
|
...failingChecks.length > 0 ? { failingChecks: failingChecks.map((check) => check.name).join(", ") } : {},
|
|
906
982
|
...pendingChecks.length > 0 ? { pendingChecks: pendingChecks.map((check) => check.name).join(", ") } : {}
|
|
907
983
|
},
|
|
@@ -930,11 +1006,19 @@ var GithubSignals = class extends SignalProvider {
|
|
|
930
1006
|
latestCommentAuthor: input.snapshot.latestCommentAuthor,
|
|
931
1007
|
latestCommentAuthorType: input.snapshot.latestCommentAuthorType,
|
|
932
1008
|
latestCommentIsBot: input.snapshot.latestCommentIsBot,
|
|
1009
|
+
latestCommentBody: input.snapshot.latestCommentBody,
|
|
1010
|
+
latestCommentExcerpt,
|
|
1011
|
+
latestCommentUrl: input.snapshot.latestCommentUrl,
|
|
1012
|
+
latestCommentUpdatedAt: input.snapshot.latestCommentUpdatedAt,
|
|
933
1013
|
failingChecks,
|
|
934
1014
|
pendingChecks
|
|
935
1015
|
}
|
|
936
1016
|
}
|
|
937
1017
|
};
|
|
1018
|
+
return notificationInput;
|
|
1019
|
+
}
|
|
1020
|
+
async #sendGithubNotification(input) {
|
|
1021
|
+
const notificationInput = this.#createGithubNotificationInput(input);
|
|
938
1022
|
const streamOptions = await this.#agentOptions.getNotificationStreamOptions?.(input.target);
|
|
939
1023
|
await input.agent?.sendNotificationSignal?.(
|
|
940
1024
|
notificationInput,
|
|
@@ -953,25 +1037,144 @@ var GithubSignals = class extends SignalProvider {
|
|
|
953
1037
|
dedupeSuffix: `baseline:${input.subscription.lastSubscribeSignalId}`
|
|
954
1038
|
});
|
|
955
1039
|
}
|
|
956
|
-
async #
|
|
1040
|
+
async #isAuthorizedAuthor(owner, repo, user, metadata = {}) {
|
|
1041
|
+
if (!user) return false;
|
|
1042
|
+
const normalizedUser = user.toLowerCase();
|
|
1043
|
+
const isBot = metadata.isBot === true || metadata.authorType?.toLowerCase() === "bot" || normalizedUser.endsWith("[bot]");
|
|
1044
|
+
if (isBot) {
|
|
1045
|
+
const ignoredBots = this.#options.ignoredBots ?? [];
|
|
1046
|
+
if (ignoredBots.some((bot) => bot.toLowerCase() === normalizedUser)) return false;
|
|
1047
|
+
const authorizedBots = this.#options.authorizedBots ?? DEFAULT_AUTHORIZED_BOTS;
|
|
1048
|
+
return authorizedBots.some((bot) => bot.toLowerCase() === normalizedUser);
|
|
1049
|
+
}
|
|
1050
|
+
const permission = await this.#loadAuthorPermission(owner, repo, user);
|
|
1051
|
+
const authorizedPermissions = this.#options.authorizedPermissions ?? DEFAULT_AUTHORIZED_PERMISSIONS;
|
|
1052
|
+
return !!permission && authorizedPermissions.includes(permission);
|
|
1053
|
+
}
|
|
1054
|
+
async #filterUnauthorizedLatestComment(owner, repo, snapshot) {
|
|
1055
|
+
const comments = snapshot.latestComments?.length ? snapshot.latestComments : [
|
|
1056
|
+
{
|
|
1057
|
+
author: snapshot.latestCommentAuthor,
|
|
1058
|
+
authorType: snapshot.latestCommentAuthorType,
|
|
1059
|
+
isBot: snapshot.latestCommentIsBot,
|
|
1060
|
+
body: snapshot.latestCommentBody,
|
|
1061
|
+
url: snapshot.latestCommentUrl,
|
|
1062
|
+
updatedAt: snapshot.latestCommentUpdatedAt
|
|
1063
|
+
}
|
|
1064
|
+
];
|
|
1065
|
+
if (!comments.some((comment) => comment.author)) return snapshot;
|
|
1066
|
+
if (!comments.some((comment) => comment.body || comment.url || comment.updatedAt)) return snapshot;
|
|
1067
|
+
for (const comment of comments) {
|
|
1068
|
+
if (!await this.#isAuthorizedAuthor(owner, repo, comment.author, {
|
|
1069
|
+
authorType: comment.authorType,
|
|
1070
|
+
isBot: comment.isBot
|
|
1071
|
+
})) {
|
|
1072
|
+
continue;
|
|
1073
|
+
}
|
|
1074
|
+
return {
|
|
1075
|
+
...snapshot,
|
|
1076
|
+
latestCommentAuthor: comment.author,
|
|
1077
|
+
latestCommentAuthorType: comment.authorType,
|
|
1078
|
+
latestCommentIsBot: comment.isBot,
|
|
1079
|
+
latestCommentBody: comment.body,
|
|
1080
|
+
latestCommentUrl: comment.url,
|
|
1081
|
+
latestCommentUpdatedAt: comment.updatedAt
|
|
1082
|
+
};
|
|
1083
|
+
}
|
|
1084
|
+
return {
|
|
1085
|
+
...snapshot,
|
|
1086
|
+
latestCommentAuthor: void 0,
|
|
1087
|
+
latestCommentAuthorType: void 0,
|
|
1088
|
+
latestCommentIsBot: void 0,
|
|
1089
|
+
latestCommentBody: void 0,
|
|
1090
|
+
latestCommentUrl: void 0,
|
|
1091
|
+
latestCommentUpdatedAt: void 0
|
|
1092
|
+
};
|
|
1093
|
+
}
|
|
1094
|
+
async #loadAuthorPermission(owner, repo, user) {
|
|
1095
|
+
const cacheKey = `${owner}/${repo}:${user.toLowerCase()}`;
|
|
1096
|
+
const cached = this.#permissionCache.get(cacheKey);
|
|
1097
|
+
if (cached && cached.expiresAt > Date.now()) return cached.permission;
|
|
1098
|
+
if (cached) this.#permissionCache.delete(cacheKey);
|
|
1099
|
+
try {
|
|
1100
|
+
let permission;
|
|
1101
|
+
if (this.#options.permissionResolver) {
|
|
1102
|
+
permission = await this.#options.permissionResolver.getPermission(owner, repo, user);
|
|
1103
|
+
} else {
|
|
1104
|
+
const { stdout } = await execFileAsync("gh", [
|
|
1105
|
+
"api",
|
|
1106
|
+
`repos/${owner}/${repo}/collaborators/${user}/permission`,
|
|
1107
|
+
"--jq",
|
|
1108
|
+
".permission"
|
|
1109
|
+
]);
|
|
1110
|
+
const raw = stdout.trim();
|
|
1111
|
+
permission = ["admin", "maintain", "write", "triage", "read", "none"].includes(
|
|
1112
|
+
raw
|
|
1113
|
+
) ? raw : void 0;
|
|
1114
|
+
}
|
|
1115
|
+
if (permission) {
|
|
1116
|
+
this.#permissionCache.set(cacheKey, { permission, expiresAt: Date.now() + PERMISSION_CACHE_TTL_MS });
|
|
1117
|
+
}
|
|
1118
|
+
return permission;
|
|
1119
|
+
} catch {
|
|
1120
|
+
this.#permissionCache.delete(cacheKey);
|
|
1121
|
+
return void 0;
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
async #sendActivityNotifications(input) {
|
|
957
1125
|
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
|
-
|
|
1126
|
+
if (!agent?.sendNotificationSignal) return [];
|
|
1127
|
+
const notifications = [
|
|
1128
|
+
classifyGithubActivityNotification({
|
|
1129
|
+
subscription: input.subscription,
|
|
1130
|
+
snapshot: input.snapshot
|
|
1131
|
+
})
|
|
1132
|
+
];
|
|
1133
|
+
if (input.latestCommentChanged && notifications[0]?.kind !== "pull-request-activity") {
|
|
1134
|
+
notifications.push(
|
|
1135
|
+
classifyGithubCommentActivityNotification({
|
|
1136
|
+
subscription: input.subscription,
|
|
1137
|
+
snapshot: input.snapshot
|
|
1138
|
+
})
|
|
1139
|
+
);
|
|
1140
|
+
}
|
|
1141
|
+
const sent = [];
|
|
1142
|
+
const notificationInputs = [];
|
|
1143
|
+
for (const notification of notifications.sort(compareGithubActivityNotifications)) {
|
|
1144
|
+
if (!notification) continue;
|
|
1145
|
+
if (AUTHOR_GATED_NOTIFICATION_KINDS.has(notification.kind)) {
|
|
1146
|
+
const authorized = await this.#isAuthorizedAuthor(
|
|
1147
|
+
input.subscription.owner,
|
|
1148
|
+
input.subscription.repo,
|
|
1149
|
+
input.snapshot.latestCommentAuthor,
|
|
1150
|
+
{
|
|
1151
|
+
authorType: input.snapshot.latestCommentAuthorType,
|
|
1152
|
+
isBot: input.snapshot.latestCommentIsBot
|
|
1153
|
+
}
|
|
1154
|
+
);
|
|
1155
|
+
if (!authorized) continue;
|
|
1156
|
+
}
|
|
1157
|
+
notificationInputs.push(
|
|
1158
|
+
this.#createGithubNotificationInput({
|
|
1159
|
+
subscription: input.subscription,
|
|
1160
|
+
snapshot: input.snapshot,
|
|
1161
|
+
notification,
|
|
1162
|
+
dedupeSuffix: input.snapshot.contentHash ?? input.snapshot.githubUpdatedAt ?? String(Date.now()),
|
|
1163
|
+
previousGithubUpdatedAt: input.previousGithubUpdatedAt,
|
|
1164
|
+
previousContentHash: input.previousContentHash
|
|
1165
|
+
})
|
|
1166
|
+
);
|
|
1167
|
+
sent.push(notification);
|
|
1168
|
+
}
|
|
1169
|
+
if (notificationInputs.length > 0) {
|
|
1170
|
+
const target = { resourceId: input.polling.resourceId, threadId: input.polling.threadId };
|
|
1171
|
+
const streamOptions = await this.#agentOptions.getNotificationStreamOptions?.(target);
|
|
1172
|
+
await agent.sendNotificationSignal(
|
|
1173
|
+
notificationInputs,
|
|
1174
|
+
streamOptions ? { ...target, ifIdle: { streamOptions } } : target
|
|
1175
|
+
);
|
|
1176
|
+
}
|
|
1177
|
+
return sent;
|
|
975
1178
|
}
|
|
976
1179
|
async #subscribe(input) {
|
|
977
1180
|
const { owner, repo } = await this.#resolveRepository(input);
|