@holon-run/agentinbox 0.1.0 → 0.1.3
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/README.md +76 -16
- package/dist/src/adapters.js +38 -31
- package/dist/src/cli.js +279 -66
- package/dist/src/current_agent.js +126 -0
- package/dist/src/http.js +962 -354
- package/dist/src/service.js +94 -10
- package/dist/src/source_schema.js +2 -10
- package/dist/src/sources/feishu.js +14 -237
- package/dist/src/sources/github.js +10 -244
- package/dist/src/sources/github_ci.js +13 -12
- package/dist/src/sources/remote.js +362 -0
- package/dist/src/sources/remote_profiles.js +254 -0
- package/dist/src/store.js +119 -248
- package/dist/src/util.js +19 -3
- package/drizzle/migrations/0000_initial.sql +206 -0
- package/drizzle/migrations/0001_inbox_items_source_occurred_at_idx.sql +3 -0
- package/drizzle/migrations/meta/0001_snapshot.json +1181 -0
- package/drizzle/migrations/meta/_journal.json +20 -0
- package/drizzle/schema.ts +196 -0
- package/package.json +8 -2
- package/dist/src/matcher.js +0 -47
|
@@ -1,76 +1,24 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.GithubDeliveryAdapter = exports.
|
|
3
|
+
exports.GithubDeliveryAdapter = exports.GithubUxcClient = exports.DEFAULT_GITHUB_EVENT_TYPES = exports.GITHUB_ENDPOINT = void 0;
|
|
4
4
|
exports.normalizeGithubRepoEvent = normalizeGithubRepoEvent;
|
|
5
|
+
exports.parseGithubSourceConfig = parseGithubSourceConfig;
|
|
5
6
|
const uxc_daemon_client_1 = require("@holon-run/uxc-daemon-client");
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
exports.GITHUB_ENDPOINT = "https://api.github.com";
|
|
8
|
+
exports.DEFAULT_GITHUB_EVENT_TYPES = [
|
|
8
9
|
"IssuesEvent",
|
|
9
10
|
"IssueCommentEvent",
|
|
10
11
|
"PullRequestEvent",
|
|
11
12
|
"PullRequestReviewCommentEvent",
|
|
12
13
|
];
|
|
13
|
-
const MAX_ERROR_BACKOFF_MULTIPLIER = 8;
|
|
14
14
|
class GithubUxcClient {
|
|
15
15
|
client;
|
|
16
16
|
constructor(client = new uxc_daemon_client_1.UxcDaemonClient({ env: process.env })) {
|
|
17
17
|
this.client = client;
|
|
18
18
|
}
|
|
19
|
-
async ensureRepoEventsSubscription(config, checkpoint) {
|
|
20
|
-
if (checkpoint.uxcJobId) {
|
|
21
|
-
try {
|
|
22
|
-
const status = await this.client.subscribeStatus(checkpoint.uxcJobId);
|
|
23
|
-
if (status.status === "running" || status.status === "reconnecting") {
|
|
24
|
-
return {
|
|
25
|
-
job_id: checkpoint.uxcJobId,
|
|
26
|
-
mode: "poll",
|
|
27
|
-
protocol: "openapi",
|
|
28
|
-
endpoint: GITHUB_ENDPOINT,
|
|
29
|
-
sink: "memory:",
|
|
30
|
-
status: status.status,
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
catch {
|
|
35
|
-
// Recreate the job below.
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
const started = await this.client.subscribeStart({
|
|
39
|
-
endpoint: GITHUB_ENDPOINT,
|
|
40
|
-
operationId: "get:/repos/{owner}/{repo}/events",
|
|
41
|
-
args: { owner: config.owner, repo: config.repo, per_page: config.perPage ?? 10 },
|
|
42
|
-
mode: "poll",
|
|
43
|
-
pollConfig: {
|
|
44
|
-
interval_secs: config.pollIntervalSecs ?? 30,
|
|
45
|
-
extract_items_pointer: "",
|
|
46
|
-
checkpoint_strategy: {
|
|
47
|
-
type: "item_key",
|
|
48
|
-
item_key_pointer: "/id",
|
|
49
|
-
seen_window: 1024,
|
|
50
|
-
},
|
|
51
|
-
},
|
|
52
|
-
options: { auth: config.uxcAuth },
|
|
53
|
-
sink: "memory:",
|
|
54
|
-
ephemeral: false,
|
|
55
|
-
});
|
|
56
|
-
return started;
|
|
57
|
-
}
|
|
58
|
-
async readSubscriptionEvents(jobId, afterSeq) {
|
|
59
|
-
const response = await this.client.subscriptionEvents({
|
|
60
|
-
jobId,
|
|
61
|
-
afterSeq,
|
|
62
|
-
limit: 100,
|
|
63
|
-
waitMs: 10,
|
|
64
|
-
});
|
|
65
|
-
return {
|
|
66
|
-
events: response.events,
|
|
67
|
-
nextAfterSeq: response.next_after_seq,
|
|
68
|
-
status: response.status,
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
19
|
async createIssueComment(input) {
|
|
72
20
|
await this.client.call({
|
|
73
|
-
endpoint: GITHUB_ENDPOINT,
|
|
21
|
+
endpoint: exports.GITHUB_ENDPOINT,
|
|
74
22
|
operation: "post:/repos/{owner}/{repo}/issues/{issue_number}/comments",
|
|
75
23
|
payload: {
|
|
76
24
|
owner: input.owner,
|
|
@@ -83,7 +31,7 @@ class GithubUxcClient {
|
|
|
83
31
|
}
|
|
84
32
|
async replyToReviewComment(input) {
|
|
85
33
|
await this.client.call({
|
|
86
|
-
endpoint: GITHUB_ENDPOINT,
|
|
34
|
+
endpoint: exports.GITHUB_ENDPOINT,
|
|
87
35
|
operation: "post:/repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies",
|
|
88
36
|
payload: {
|
|
89
37
|
owner: input.owner,
|
|
@@ -97,177 +45,6 @@ class GithubUxcClient {
|
|
|
97
45
|
}
|
|
98
46
|
}
|
|
99
47
|
exports.GithubUxcClient = GithubUxcClient;
|
|
100
|
-
class GithubSourceRuntime {
|
|
101
|
-
store;
|
|
102
|
-
appendSourceEvent;
|
|
103
|
-
client;
|
|
104
|
-
interval = null;
|
|
105
|
-
inFlight = new Set();
|
|
106
|
-
errorCounts = new Map();
|
|
107
|
-
nextRetryAt = new Map();
|
|
108
|
-
constructor(store, appendSourceEvent, client) {
|
|
109
|
-
this.store = store;
|
|
110
|
-
this.appendSourceEvent = appendSourceEvent;
|
|
111
|
-
this.client = client ?? new GithubUxcClient();
|
|
112
|
-
}
|
|
113
|
-
async ensureSource(source) {
|
|
114
|
-
if (source.sourceType !== "github_repo") {
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
const config = parseGithubSourceConfig(source);
|
|
118
|
-
const checkpoint = parseGithubCheckpoint(source.checkpoint);
|
|
119
|
-
const started = await this.client.ensureRepoEventsSubscription(config, checkpoint);
|
|
120
|
-
this.store.updateSourceRuntime(source.sourceId, {
|
|
121
|
-
status: "active",
|
|
122
|
-
checkpoint: JSON.stringify({
|
|
123
|
-
...checkpoint,
|
|
124
|
-
uxcJobId: started.job_id,
|
|
125
|
-
}),
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
async start() {
|
|
129
|
-
if (this.interval) {
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
this.interval = setInterval(() => {
|
|
133
|
-
void this.syncAll();
|
|
134
|
-
}, 2_000);
|
|
135
|
-
try {
|
|
136
|
-
await this.syncAll();
|
|
137
|
-
}
|
|
138
|
-
catch (error) {
|
|
139
|
-
console.warn("github_repo initial sync failed:", error);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
async stop() {
|
|
143
|
-
if (this.interval) {
|
|
144
|
-
clearInterval(this.interval);
|
|
145
|
-
this.interval = null;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
async pollSource(sourceId) {
|
|
149
|
-
return this.syncSource(sourceId);
|
|
150
|
-
}
|
|
151
|
-
status() {
|
|
152
|
-
return {
|
|
153
|
-
activeSourceIds: Array.from(this.inFlight.values()).sort(),
|
|
154
|
-
erroredSourceIds: Array.from(this.errorCounts.keys()).sort(),
|
|
155
|
-
};
|
|
156
|
-
}
|
|
157
|
-
async syncAll() {
|
|
158
|
-
const sources = this.store
|
|
159
|
-
.listSources()
|
|
160
|
-
.filter((source) => source.sourceType === "github_repo" && source.status !== "paused");
|
|
161
|
-
for (const source of sources) {
|
|
162
|
-
try {
|
|
163
|
-
await this.syncSource(source.sourceId);
|
|
164
|
-
}
|
|
165
|
-
catch (error) {
|
|
166
|
-
console.warn(`github_repo sync failed for ${source.sourceId}:`, error);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
async syncSource(sourceId) {
|
|
171
|
-
if (this.inFlight.has(sourceId)) {
|
|
172
|
-
return {
|
|
173
|
-
sourceId,
|
|
174
|
-
sourceType: "github_repo",
|
|
175
|
-
appended: 0,
|
|
176
|
-
deduped: 0,
|
|
177
|
-
eventsRead: 0,
|
|
178
|
-
note: "source sync already in flight",
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
this.inFlight.add(sourceId);
|
|
182
|
-
try {
|
|
183
|
-
const source = this.store.getSource(sourceId);
|
|
184
|
-
if (!source) {
|
|
185
|
-
throw new Error(`unknown source: ${sourceId}`);
|
|
186
|
-
}
|
|
187
|
-
const config = parseGithubSourceConfig(source);
|
|
188
|
-
if (source.status === "error") {
|
|
189
|
-
const retryAt = this.nextRetryAt.get(sourceId) ?? 0;
|
|
190
|
-
if (Date.now() < retryAt) {
|
|
191
|
-
return {
|
|
192
|
-
sourceId,
|
|
193
|
-
sourceType: "github_repo",
|
|
194
|
-
appended: 0,
|
|
195
|
-
deduped: 0,
|
|
196
|
-
eventsRead: 0,
|
|
197
|
-
note: "error backoff not elapsed",
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
let checkpoint = parseGithubCheckpoint(source.checkpoint);
|
|
202
|
-
const subscription = await this.client.ensureRepoEventsSubscription(config, checkpoint);
|
|
203
|
-
if (subscription.job_id !== checkpoint.uxcJobId) {
|
|
204
|
-
checkpoint = { ...checkpoint, uxcJobId: subscription.job_id };
|
|
205
|
-
}
|
|
206
|
-
const batch = await this.client.readSubscriptionEvents(checkpoint.uxcJobId, checkpoint.afterSeq ?? 0);
|
|
207
|
-
let appended = 0;
|
|
208
|
-
let deduped = 0;
|
|
209
|
-
for (const event of batch.events) {
|
|
210
|
-
if (event.event_kind !== "data") {
|
|
211
|
-
continue;
|
|
212
|
-
}
|
|
213
|
-
const normalized = normalizeGithubRepoEvent(source, config, event.data);
|
|
214
|
-
if (!normalized) {
|
|
215
|
-
continue;
|
|
216
|
-
}
|
|
217
|
-
const result = await this.appendSourceEvent(normalized);
|
|
218
|
-
appended += result.appended;
|
|
219
|
-
deduped += result.deduped;
|
|
220
|
-
}
|
|
221
|
-
this.store.updateSourceRuntime(sourceId, {
|
|
222
|
-
status: "active",
|
|
223
|
-
checkpoint: JSON.stringify({
|
|
224
|
-
...checkpoint,
|
|
225
|
-
uxcJobId: checkpoint.uxcJobId,
|
|
226
|
-
afterSeq: batch.nextAfterSeq,
|
|
227
|
-
lastEventAt: new Date().toISOString(),
|
|
228
|
-
lastError: null,
|
|
229
|
-
}),
|
|
230
|
-
});
|
|
231
|
-
this.errorCounts.delete(sourceId);
|
|
232
|
-
this.nextRetryAt.delete(sourceId);
|
|
233
|
-
return {
|
|
234
|
-
sourceId,
|
|
235
|
-
sourceType: "github_repo",
|
|
236
|
-
appended,
|
|
237
|
-
deduped,
|
|
238
|
-
eventsRead: batch.events.length,
|
|
239
|
-
note: `subscription status=${batch.status}`,
|
|
240
|
-
};
|
|
241
|
-
}
|
|
242
|
-
catch (error) {
|
|
243
|
-
const source = this.store.getSource(sourceId);
|
|
244
|
-
if (source) {
|
|
245
|
-
const checkpoint = parseGithubCheckpoint(source.checkpoint);
|
|
246
|
-
const config = parseGithubSourceConfig(source);
|
|
247
|
-
const nextErrorCount = (this.errorCounts.get(sourceId) ?? 0) + 1;
|
|
248
|
-
this.errorCounts.set(sourceId, nextErrorCount);
|
|
249
|
-
this.nextRetryAt.set(sourceId, Date.now() + computeErrorBackoffMs(config.pollIntervalSecs ?? 30, nextErrorCount));
|
|
250
|
-
this.store.updateSourceRuntime(sourceId, {
|
|
251
|
-
status: "error",
|
|
252
|
-
checkpoint: JSON.stringify({
|
|
253
|
-
...checkpoint,
|
|
254
|
-
lastError: error instanceof Error ? error.message : String(error),
|
|
255
|
-
}),
|
|
256
|
-
});
|
|
257
|
-
}
|
|
258
|
-
throw error;
|
|
259
|
-
}
|
|
260
|
-
finally {
|
|
261
|
-
this.inFlight.delete(sourceId);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
exports.GithubSourceRuntime = GithubSourceRuntime;
|
|
266
|
-
function computeErrorBackoffMs(pollIntervalSecs, errorCount) {
|
|
267
|
-
const baseMs = Math.max(1, pollIntervalSecs) * 1000;
|
|
268
|
-
const multiplier = Math.min(2 ** Math.max(0, errorCount - 1), MAX_ERROR_BACKOFF_MULTIPLIER);
|
|
269
|
-
return baseMs * multiplier;
|
|
270
|
-
}
|
|
271
48
|
class GithubDeliveryAdapter {
|
|
272
49
|
client;
|
|
273
50
|
constructor(client) {
|
|
@@ -308,7 +85,7 @@ function normalizeGithubRepoEvent(source, config, raw) {
|
|
|
308
85
|
}
|
|
309
86
|
const event = raw;
|
|
310
87
|
const eventType = asString(event.type);
|
|
311
|
-
if (!eventType || !(config.eventTypes ??
|
|
88
|
+
if (!eventType || !(config.eventTypes ?? exports.DEFAULT_GITHUB_EVENT_TYPES).includes(eventType)) {
|
|
312
89
|
return null;
|
|
313
90
|
}
|
|
314
91
|
const eventId = asString(event.id);
|
|
@@ -331,7 +108,7 @@ function normalizeGithubRepoEvent(source, config, raw) {
|
|
|
331
108
|
const url = asString(comment.html_url) ??
|
|
332
109
|
asString(issue.html_url) ??
|
|
333
110
|
asString(pullRequest.html_url) ??
|
|
334
|
-
asString(event
|
|
111
|
+
asString(event.url);
|
|
335
112
|
const deliveryHandle = buildGithubDeliveryHandle(config, eventType, number, comment);
|
|
336
113
|
return {
|
|
337
114
|
sourceId: source.sourceId,
|
|
@@ -403,7 +180,7 @@ function parseGithubSourceConfig(source) {
|
|
|
403
180
|
uxcAuth: asString(config.uxcAuth) ?? asString(config.credentialRef) ?? undefined,
|
|
404
181
|
pollIntervalSecs: asNumber(config.pollIntervalSecs) ?? 30,
|
|
405
182
|
perPage: asNumber(config.perPage) ?? 10,
|
|
406
|
-
eventTypes: asStringArray(config.eventTypes) ??
|
|
183
|
+
eventTypes: asStringArray(config.eventTypes) ?? exports.DEFAULT_GITHUB_EVENT_TYPES,
|
|
407
184
|
};
|
|
408
185
|
}
|
|
409
186
|
return {
|
|
@@ -412,20 +189,9 @@ function parseGithubSourceConfig(source) {
|
|
|
412
189
|
uxcAuth: asString(config.uxcAuth) ?? asString(config.credentialRef) ?? undefined,
|
|
413
190
|
pollIntervalSecs: asNumber(config.pollIntervalSecs) ?? 30,
|
|
414
191
|
perPage: asNumber(config.perPage) ?? 10,
|
|
415
|
-
eventTypes: asStringArray(config.eventTypes) ??
|
|
192
|
+
eventTypes: asStringArray(config.eventTypes) ?? exports.DEFAULT_GITHUB_EVENT_TYPES,
|
|
416
193
|
};
|
|
417
194
|
}
|
|
418
|
-
function parseGithubCheckpoint(checkpoint) {
|
|
419
|
-
if (!checkpoint) {
|
|
420
|
-
return {};
|
|
421
|
-
}
|
|
422
|
-
try {
|
|
423
|
-
return JSON.parse(checkpoint);
|
|
424
|
-
}
|
|
425
|
-
catch {
|
|
426
|
-
return {};
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
195
|
function extractLabels(raw) {
|
|
430
196
|
if (!Array.isArray(raw)) {
|
|
431
197
|
return [];
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.GithubCiSourceRuntime = exports.GithubActionsUxcClient = void 0;
|
|
3
|
+
exports.GithubCiSourceRuntime = exports.GithubActionsUxcClient = exports.DEFAULT_GITHUB_CI_PER_PAGE = exports.DEFAULT_GITHUB_CI_POLL_INTERVAL_SECS = exports.GITHUB_CI_ENDPOINT = void 0;
|
|
4
4
|
exports.normalizeGithubWorkflowRunEvent = normalizeGithubWorkflowRunEvent;
|
|
5
|
+
exports.parseGithubCiSourceConfig = parseGithubCiSourceConfig;
|
|
5
6
|
const uxc_daemon_client_1 = require("@holon-run/uxc-daemon-client");
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
exports.GITHUB_CI_ENDPOINT = "https://api.github.com";
|
|
8
|
+
exports.DEFAULT_GITHUB_CI_POLL_INTERVAL_SECS = 30;
|
|
9
|
+
exports.DEFAULT_GITHUB_CI_PER_PAGE = 20;
|
|
9
10
|
const MAX_SEEN_KEYS = 512;
|
|
10
11
|
const MAX_ERROR_BACKOFF_MULTIPLIER = 8;
|
|
11
12
|
class GithubActionsUxcClient {
|
|
@@ -17,7 +18,7 @@ class GithubActionsUxcClient {
|
|
|
17
18
|
const payload = {
|
|
18
19
|
owner: config.owner,
|
|
19
20
|
repo: config.repo,
|
|
20
|
-
per_page: config.perPage ??
|
|
21
|
+
per_page: config.perPage ?? exports.DEFAULT_GITHUB_CI_PER_PAGE,
|
|
21
22
|
};
|
|
22
23
|
if (config.eventFilter) {
|
|
23
24
|
payload.event = config.eventFilter;
|
|
@@ -29,7 +30,7 @@ class GithubActionsUxcClient {
|
|
|
29
30
|
payload.status = config.statusFilter;
|
|
30
31
|
}
|
|
31
32
|
const response = await this.client.call({
|
|
32
|
-
endpoint:
|
|
33
|
+
endpoint: exports.GITHUB_CI_ENDPOINT,
|
|
33
34
|
operation: "get:/repos/{owner}/{repo}/actions/runs",
|
|
34
35
|
payload,
|
|
35
36
|
options: { auth: config.uxcAuth },
|
|
@@ -138,7 +139,7 @@ class GithubCiSourceRuntime {
|
|
|
138
139
|
};
|
|
139
140
|
}
|
|
140
141
|
const lastPollAt = this.lastPollAt.get(sourceId) ?? 0;
|
|
141
|
-
const pollIntervalMs = (config.pollIntervalSecs ??
|
|
142
|
+
const pollIntervalMs = (config.pollIntervalSecs ?? exports.DEFAULT_GITHUB_CI_POLL_INTERVAL_SECS) * 1000;
|
|
142
143
|
if (Date.now() - lastPollAt < pollIntervalMs) {
|
|
143
144
|
return {
|
|
144
145
|
sourceId,
|
|
@@ -205,7 +206,7 @@ class GithubCiSourceRuntime {
|
|
|
205
206
|
const config = parseGithubCiSourceConfig(source);
|
|
206
207
|
const nextErrorCount = (this.errorCounts.get(sourceId) ?? 0) + 1;
|
|
207
208
|
this.errorCounts.set(sourceId, nextErrorCount);
|
|
208
|
-
this.nextRetryAt.set(sourceId, Date.now() + computeErrorBackoffMs(config.pollIntervalSecs ??
|
|
209
|
+
this.nextRetryAt.set(sourceId, Date.now() + computeErrorBackoffMs(config.pollIntervalSecs ?? exports.DEFAULT_GITHUB_CI_POLL_INTERVAL_SECS, nextErrorCount));
|
|
209
210
|
this.store.updateSourceRuntime(sourceId, {
|
|
210
211
|
status: "error",
|
|
211
212
|
checkpoint: JSON.stringify({
|
|
@@ -301,8 +302,8 @@ function parseGithubCiSourceConfig(source) {
|
|
|
301
302
|
owner: fallbackOwner,
|
|
302
303
|
repo: fallbackRepo,
|
|
303
304
|
uxcAuth: asString(config.uxcAuth) ?? asString(config.credentialRef) ?? undefined,
|
|
304
|
-
pollIntervalSecs: asNumber(config.pollIntervalSecs) ??
|
|
305
|
-
perPage: asNumber(config.perPage) ??
|
|
305
|
+
pollIntervalSecs: asNumber(config.pollIntervalSecs) ?? exports.DEFAULT_GITHUB_CI_POLL_INTERVAL_SECS,
|
|
306
|
+
perPage: asNumber(config.perPage) ?? exports.DEFAULT_GITHUB_CI_PER_PAGE,
|
|
306
307
|
eventFilter: asString(config.eventFilter) ?? undefined,
|
|
307
308
|
branch: asString(config.branch) ?? undefined,
|
|
308
309
|
statusFilter: asString(config.statusFilter) ?? undefined,
|
|
@@ -312,8 +313,8 @@ function parseGithubCiSourceConfig(source) {
|
|
|
312
313
|
owner,
|
|
313
314
|
repo,
|
|
314
315
|
uxcAuth: asString(config.uxcAuth) ?? asString(config.credentialRef) ?? undefined,
|
|
315
|
-
pollIntervalSecs: asNumber(config.pollIntervalSecs) ??
|
|
316
|
-
perPage: asNumber(config.perPage) ??
|
|
316
|
+
pollIntervalSecs: asNumber(config.pollIntervalSecs) ?? exports.DEFAULT_GITHUB_CI_POLL_INTERVAL_SECS,
|
|
317
|
+
perPage: asNumber(config.perPage) ?? exports.DEFAULT_GITHUB_CI_PER_PAGE,
|
|
317
318
|
eventFilter: asString(config.eventFilter) ?? undefined,
|
|
318
319
|
branch: asString(config.branch) ?? undefined,
|
|
319
320
|
statusFilter: asString(config.statusFilter) ?? undefined,
|