@agentworkforce/sage 1.1.3 → 1.2.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.
Files changed (53) hide show
  1. package/dist/app.d.ts.map +1 -1
  2. package/dist/app.js +54 -29
  3. package/dist/e2e/e2e-harness.d.ts +36 -0
  4. package/dist/e2e/e2e-harness.d.ts.map +1 -0
  5. package/dist/e2e/e2e-harness.js +278 -0
  6. package/dist/e2e/mock-cloud-proxy-server.d.ts +25 -0
  7. package/dist/e2e/mock-cloud-proxy-server.d.ts.map +1 -0
  8. package/dist/e2e/mock-cloud-proxy-server.js +149 -0
  9. package/dist/e2e/mock-relayfile-server.d.ts +35 -0
  10. package/dist/e2e/mock-relayfile-server.d.ts.map +1 -0
  11. package/dist/e2e/mock-relayfile-server.js +488 -0
  12. package/dist/integrations/cloud-proxy-provider.js +1 -1
  13. package/dist/integrations/freshness-envelope.js +1 -1
  14. package/dist/integrations/github.d.ts +24 -1
  15. package/dist/integrations/github.d.ts.map +1 -1
  16. package/dist/integrations/github.js +116 -1
  17. package/dist/integrations/linear-ingress.d.ts +30 -0
  18. package/dist/integrations/linear-ingress.d.ts.map +1 -0
  19. package/dist/integrations/linear-ingress.js +58 -0
  20. package/dist/integrations/notion-ingress.d.ts +26 -0
  21. package/dist/integrations/notion-ingress.d.ts.map +1 -0
  22. package/dist/integrations/notion-ingress.js +70 -0
  23. package/dist/integrations/provider-ingress-dedup.d.ts +14 -0
  24. package/dist/integrations/provider-ingress-dedup.d.ts.map +1 -0
  25. package/dist/integrations/provider-ingress-dedup.js +35 -0
  26. package/dist/integrations/provider-ingress-dedup.test.d.ts +2 -0
  27. package/dist/integrations/provider-ingress-dedup.test.d.ts.map +1 -0
  28. package/dist/integrations/provider-ingress-dedup.test.js +55 -0
  29. package/dist/integrations/provider-write-facade.d.ts +80 -0
  30. package/dist/integrations/provider-write-facade.d.ts.map +1 -0
  31. package/dist/integrations/provider-write-facade.js +417 -0
  32. package/dist/integrations/provider-write-facade.test.d.ts +2 -0
  33. package/dist/integrations/provider-write-facade.test.d.ts.map +1 -0
  34. package/dist/integrations/provider-write-facade.test.js +247 -0
  35. package/dist/integrations/read-your-writes.test.d.ts +2 -0
  36. package/dist/integrations/read-your-writes.test.d.ts.map +1 -0
  37. package/dist/integrations/read-your-writes.test.js +170 -0
  38. package/dist/integrations/recent-actions-overlay.d.ts +1 -0
  39. package/dist/integrations/recent-actions-overlay.d.ts.map +1 -1
  40. package/dist/integrations/recent-actions-overlay.js +3 -0
  41. package/dist/integrations/relayfile-reader-envelope.test.d.ts +2 -0
  42. package/dist/integrations/relayfile-reader-envelope.test.d.ts.map +1 -0
  43. package/dist/integrations/relayfile-reader-envelope.test.js +198 -0
  44. package/dist/integrations/relayfile-reader.d.ts +20 -1
  45. package/dist/integrations/relayfile-reader.d.ts.map +1 -1
  46. package/dist/integrations/relayfile-reader.js +334 -48
  47. package/dist/integrations/slack-egress.d.ts +2 -1
  48. package/dist/integrations/slack-egress.d.ts.map +1 -1
  49. package/dist/integrations/slack-egress.js +28 -1
  50. package/dist/observability.e2e.test.d.ts +2 -0
  51. package/dist/observability.e2e.test.d.ts.map +1 -0
  52. package/dist/observability.e2e.test.js +411 -0
  53. package/package.json +9 -4
@@ -0,0 +1,488 @@
1
+ import { randomBytes } from "node:crypto";
2
+ import { createServer } from "node:http";
3
+ import express from "express";
4
+ const ROUTE_PATTERN = /^\/v1\/workspaces\/([^/]+)\/fs\/(file|query|tree)$/;
5
+ function randomRevision() {
6
+ return `rev-${randomBytes(8).toString("hex")}`;
7
+ }
8
+ function normalizeVfsPath(value) {
9
+ const trimmed = value.trim();
10
+ if (!trimmed) {
11
+ return "/";
12
+ }
13
+ const withLeadingSlash = trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
14
+ return withLeadingSlash === "/" ? withLeadingSlash : withLeadingSlash.replace(/\/+$/g, "");
15
+ }
16
+ function readQueryString(value) {
17
+ if (typeof value === "string") {
18
+ return value;
19
+ }
20
+ if (Array.isArray(value)) {
21
+ return readQueryString(value[0]);
22
+ }
23
+ return undefined;
24
+ }
25
+ function parsePositiveInteger(value) {
26
+ const raw = readQueryString(value);
27
+ if (raw === undefined || raw.trim() === "") {
28
+ return null;
29
+ }
30
+ const parsed = Number.parseInt(raw, 10);
31
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
32
+ }
33
+ function parseNonNegativeInteger(value) {
34
+ const raw = readQueryString(value);
35
+ if (raw === undefined || raw.trim() === "") {
36
+ return null;
37
+ }
38
+ const parsed = Number.parseInt(raw, 10);
39
+ return Number.isFinite(parsed) && parsed >= 0 ? parsed : null;
40
+ }
41
+ function normalizeHeaders(headers) {
42
+ const normalized = {};
43
+ for (const [key, value] of Object.entries(headers)) {
44
+ if (Array.isArray(value)) {
45
+ normalized[key] = value.join(", ");
46
+ }
47
+ else if (value !== undefined) {
48
+ normalized[key] = value;
49
+ }
50
+ }
51
+ return normalized;
52
+ }
53
+ function isEmptyPlainObject(value) {
54
+ return (typeof value === "object" &&
55
+ value !== null &&
56
+ !Array.isArray(value) &&
57
+ Object.keys(value).length === 0);
58
+ }
59
+ function recordRequest(req, requestLog) {
60
+ const entry = {
61
+ method: req.method,
62
+ path: req.originalUrl,
63
+ timestamp: Date.now(),
64
+ headers: normalizeHeaders(req.headers),
65
+ };
66
+ if (req.body !== undefined && !isEmptyPlainObject(req.body)) {
67
+ entry.body = req.body;
68
+ }
69
+ requestLog.push(entry);
70
+ }
71
+ function cloneRequestLogEntry(entry) {
72
+ return {
73
+ ...entry,
74
+ headers: { ...entry.headers },
75
+ };
76
+ }
77
+ function matchRelayfileRoute(pathname) {
78
+ const match = pathname.match(ROUTE_PATTERN);
79
+ if (!match) {
80
+ return null;
81
+ }
82
+ return {
83
+ workspaceId: decodeURIComponent(match[1]),
84
+ endpoint: match[2],
85
+ };
86
+ }
87
+ function hasOwnBody(override) {
88
+ return Object.prototype.hasOwnProperty.call(override, "body");
89
+ }
90
+ function defaultErrorBody(status) {
91
+ if (status === 404) {
92
+ return { code: "not_found", message: "File not found" };
93
+ }
94
+ return {
95
+ code: status >= 500 ? "internal_error" : "mock_error",
96
+ message: `Mock Relayfile response ${status}`,
97
+ };
98
+ }
99
+ function sendJson(res, status, body) {
100
+ res.status(status).json(body);
101
+ }
102
+ function sendMalformedJson(res) {
103
+ res.status(200).type("application/json").send("{ malformed json");
104
+ }
105
+ function delayResponse(delayMs, res) {
106
+ if (delayMs === undefined || delayMs <= 0) {
107
+ return Promise.resolve(true);
108
+ }
109
+ return new Promise((resolve) => {
110
+ let settled = false;
111
+ const timer = setTimeout(() => {
112
+ finish(!res.writableEnded && !res.destroyed);
113
+ }, delayMs);
114
+ timer.unref?.();
115
+ const finish = (canRespond) => {
116
+ if (settled) {
117
+ return;
118
+ }
119
+ settled = true;
120
+ clearTimeout(timer);
121
+ res.off("close", onClose);
122
+ resolve(canRespond);
123
+ };
124
+ const onClose = () => {
125
+ finish(false);
126
+ };
127
+ res.once("close", onClose);
128
+ });
129
+ }
130
+ async function applyOverride(res, override, defaultStatus = 200, defaultBody = defaultErrorBody) {
131
+ const canRespond = await delayResponse(override.delayMs, res);
132
+ if (!canRespond) {
133
+ return true;
134
+ }
135
+ if (override.malformedJson) {
136
+ sendMalformedJson(res);
137
+ return true;
138
+ }
139
+ if (hasOwnBody(override)) {
140
+ sendJson(res, override.status ?? defaultStatus, override.body);
141
+ return true;
142
+ }
143
+ if (override.status !== undefined) {
144
+ sendJson(res, override.status, defaultBody(override.status));
145
+ return true;
146
+ }
147
+ return false;
148
+ }
149
+ function storedFileToReadResponse(file) {
150
+ return {
151
+ path: file.path,
152
+ revision: file.revision,
153
+ contentType: file.contentType,
154
+ content: file.content,
155
+ encoding: file.encoding,
156
+ provider: file.provider,
157
+ providerObjectId: file.providerObjectId,
158
+ lastEditedAt: file.lastEditedAt,
159
+ properties: file.properties ? { ...file.properties } : undefined,
160
+ };
161
+ }
162
+ function fileSize(file) {
163
+ if (file.encoding === "base64") {
164
+ try {
165
+ return Buffer.from(file.content, "base64").byteLength;
166
+ }
167
+ catch {
168
+ return Buffer.byteLength(file.content, "utf-8");
169
+ }
170
+ }
171
+ return Buffer.byteLength(file.content, "utf-8");
172
+ }
173
+ function storedFileToQueryItem(file) {
174
+ return {
175
+ path: file.path,
176
+ revision: file.revision,
177
+ contentType: file.contentType,
178
+ size: fileSize(file),
179
+ provider: file.provider,
180
+ providerObjectId: file.providerObjectId,
181
+ lastEditedAt: file.lastEditedAt,
182
+ properties: file.properties ? { ...file.properties } : undefined,
183
+ };
184
+ }
185
+ function pathMatchesPrefix(filePath, prefix) {
186
+ if (prefix === "/") {
187
+ return filePath.startsWith("/");
188
+ }
189
+ return filePath === prefix || filePath.startsWith(`${prefix}/`);
190
+ }
191
+ function readPropertyFilters(query) {
192
+ const filters = {};
193
+ for (const [key, value] of Object.entries(query)) {
194
+ if (!key.startsWith("property.")) {
195
+ continue;
196
+ }
197
+ const propertyName = key.slice("property.".length);
198
+ const propertyValue = readQueryString(value);
199
+ if (propertyName && propertyValue !== undefined) {
200
+ filters[propertyName] = propertyValue;
201
+ }
202
+ }
203
+ return filters;
204
+ }
205
+ function matchesProperties(file, filters) {
206
+ for (const [key, value] of Object.entries(filters)) {
207
+ if (file.properties?.[key] !== value) {
208
+ return false;
209
+ }
210
+ }
211
+ return true;
212
+ }
213
+ function paginateByPath(items, cursor, limit) {
214
+ const sorted = [...items].sort((left, right) => left.path.localeCompare(right.path));
215
+ const cursorIndex = cursor ? sorted.findIndex((item) => item.path === cursor) : -1;
216
+ const cursorFiltered = cursor
217
+ ? cursorIndex >= 0
218
+ ? sorted.slice(cursorIndex + 1)
219
+ : sorted.filter((item) => item.path > cursor)
220
+ : sorted;
221
+ if (limit === null) {
222
+ return {
223
+ items: cursorFiltered,
224
+ nextCursor: null,
225
+ };
226
+ }
227
+ const page = cursorFiltered.slice(0, limit);
228
+ return {
229
+ items: page,
230
+ nextCursor: cursorFiltered.length > limit ? page[page.length - 1]?.path ?? null : null,
231
+ };
232
+ }
233
+ function relativeSegments(filePath, prefix) {
234
+ if (filePath === prefix) {
235
+ return [];
236
+ }
237
+ const relative = prefix === "/" ? filePath.slice(1) : filePath.slice(prefix.length + 1);
238
+ return relative.split("/").filter(Boolean);
239
+ }
240
+ function joinVfsPath(prefix, segments) {
241
+ const suffix = segments.join("/");
242
+ if (!suffix) {
243
+ return prefix;
244
+ }
245
+ return prefix === "/" ? `/${suffix}` : `${prefix}/${suffix}`;
246
+ }
247
+ function updatedAtForFile(file) {
248
+ return file.lastEditedAt ?? new Date(file.asOf).toISOString();
249
+ }
250
+ function upsertDirectoryEntry(entries, entryPath, file) {
251
+ const existing = entries.get(entryPath);
252
+ if (existing && existing.asOf >= file.asOf) {
253
+ return;
254
+ }
255
+ entries.set(entryPath, {
256
+ asOf: file.asOf,
257
+ entry: {
258
+ path: entryPath,
259
+ type: "dir",
260
+ revision: `dir:${entryPath}`,
261
+ provider: file.provider,
262
+ updatedAt: updatedAtForFile(file),
263
+ },
264
+ });
265
+ }
266
+ function buildTreeEntries(files, dirPath, depth) {
267
+ const entries = new Map();
268
+ for (const file of files) {
269
+ if (!pathMatchesPrefix(file.path, dirPath)) {
270
+ continue;
271
+ }
272
+ const segments = relativeSegments(file.path, dirPath);
273
+ if (segments.length === 0) {
274
+ if (depth >= 0) {
275
+ entries.set(file.path, {
276
+ asOf: file.asOf,
277
+ entry: {
278
+ path: file.path,
279
+ type: "file",
280
+ revision: file.revision,
281
+ provider: file.provider,
282
+ providerObjectId: file.providerObjectId,
283
+ size: fileSize(file),
284
+ updatedAt: updatedAtForFile(file),
285
+ },
286
+ });
287
+ }
288
+ continue;
289
+ }
290
+ for (let index = 0; index < segments.length; index += 1) {
291
+ const entryDepth = index + 1;
292
+ if (entryDepth > depth) {
293
+ break;
294
+ }
295
+ const entryPath = joinVfsPath(dirPath, segments.slice(0, index + 1));
296
+ const isFile = index === segments.length - 1;
297
+ if (isFile) {
298
+ entries.set(entryPath, {
299
+ asOf: file.asOf,
300
+ entry: {
301
+ path: entryPath,
302
+ type: "file",
303
+ revision: file.revision,
304
+ provider: file.provider,
305
+ providerObjectId: file.providerObjectId,
306
+ size: fileSize(file),
307
+ updatedAt: updatedAtForFile(file),
308
+ },
309
+ });
310
+ }
311
+ else {
312
+ upsertDirectoryEntry(entries, entryPath, file);
313
+ }
314
+ }
315
+ }
316
+ return [...entries.values()]
317
+ .map((value) => value.entry)
318
+ .sort((left, right) => left.path.localeCompare(right.path));
319
+ }
320
+ function closeServer(server, sockets) {
321
+ return new Promise((resolve, reject) => {
322
+ server.close((error) => {
323
+ if (error) {
324
+ reject(error);
325
+ return;
326
+ }
327
+ resolve();
328
+ });
329
+ server.closeIdleConnections?.();
330
+ server.closeAllConnections?.();
331
+ for (const socket of sockets) {
332
+ socket.destroy();
333
+ }
334
+ });
335
+ }
336
+ export async function createMockRelayfileServer() {
337
+ const app = express();
338
+ const storage = new Map();
339
+ const overrides = new Map();
340
+ const requestLog = [];
341
+ app.disable("x-powered-by");
342
+ app.use(express.json({ limit: "1mb", type: ["application/json", "*/json"] }));
343
+ app.use(async (req, res, next) => {
344
+ recordRequest(req, requestLog);
345
+ try {
346
+ const route = matchRelayfileRoute(req.path);
347
+ if (!route) {
348
+ sendJson(res, 404, { code: "not_found", message: "Route not found" });
349
+ return;
350
+ }
351
+ if (req.method !== "GET") {
352
+ sendJson(res, 405, { code: "method_not_allowed", message: "Method not allowed" });
353
+ return;
354
+ }
355
+ if (route.endpoint === "file") {
356
+ const rawPath = readQueryString(req.query.path);
357
+ if (!rawPath) {
358
+ sendJson(res, 400, { code: "bad_request", message: "Missing required path query parameter" });
359
+ return;
360
+ }
361
+ const filePath = normalizeVfsPath(rawPath);
362
+ const override = overrides.get(filePath);
363
+ if (override && (await applyOverride(res, override))) {
364
+ return;
365
+ }
366
+ const file = storage.get(filePath);
367
+ if (!file) {
368
+ sendJson(res, 404, { code: "not_found", message: "File not found" });
369
+ return;
370
+ }
371
+ sendJson(res, 200, storedFileToReadResponse(file));
372
+ return;
373
+ }
374
+ if (route.endpoint === "query") {
375
+ const pathPrefix = normalizeVfsPath(readQueryString(req.query.path) ?? "/");
376
+ const pathOverride = overrides.get(pathPrefix);
377
+ if (pathOverride?.status === 404 &&
378
+ (await applyOverride(res, pathOverride, 404, () => ({
379
+ code: "not_found",
380
+ message: "Path not found",
381
+ })))) {
382
+ return;
383
+ }
384
+ const provider = readQueryString(req.query.provider)?.trim() || undefined;
385
+ const propertyFilters = readPropertyFilters(req.query);
386
+ const cursor = readQueryString(req.query.cursor);
387
+ const limit = parsePositiveInteger(req.query.limit);
388
+ const filtered = [...storage.values()]
389
+ .filter((file) => pathMatchesPrefix(file.path, pathPrefix))
390
+ .filter((file) => provider === undefined || file.provider === provider)
391
+ .filter((file) => matchesProperties(file, propertyFilters))
392
+ .map(storedFileToQueryItem);
393
+ const page = paginateByPath(filtered, cursor, limit);
394
+ sendJson(res, 200, {
395
+ items: page.items,
396
+ nextCursor: page.nextCursor,
397
+ });
398
+ return;
399
+ }
400
+ const treePath = normalizeVfsPath(readQueryString(req.query.path) ?? "/");
401
+ const depth = parseNonNegativeInteger(req.query.depth) ?? Number.POSITIVE_INFINITY;
402
+ const cursor = readQueryString(req.query.cursor);
403
+ const entries = buildTreeEntries(storage.values(), treePath, depth);
404
+ const page = paginateByPath(entries, cursor, null);
405
+ sendJson(res, 200, {
406
+ path: treePath,
407
+ entries: page.items,
408
+ nextCursor: page.nextCursor,
409
+ });
410
+ }
411
+ catch (error) {
412
+ next(error);
413
+ }
414
+ });
415
+ app.use((error, _req, res, next) => {
416
+ if (res.headersSent) {
417
+ next(error);
418
+ return;
419
+ }
420
+ const message = error instanceof Error && error.message ? error.message : "Mock Relayfile server error";
421
+ sendJson(res, 500, {
422
+ code: "internal_error",
423
+ message,
424
+ });
425
+ });
426
+ const server = createServer(app);
427
+ const sockets = new Set();
428
+ let closed = false;
429
+ server.keepAliveTimeout = 0;
430
+ server.headersTimeout = 0;
431
+ server.on("connection", (socket) => {
432
+ sockets.add(socket);
433
+ socket.on("close", () => {
434
+ sockets.delete(socket);
435
+ });
436
+ });
437
+ await new Promise((resolve, reject) => {
438
+ server.once("error", reject);
439
+ server.listen(0, "127.0.0.1", () => {
440
+ server.off("error", reject);
441
+ resolve();
442
+ });
443
+ });
444
+ const address = server.address();
445
+ if (!address || typeof address === "string") {
446
+ await closeServer(server, sockets);
447
+ throw new Error("Mock Relayfile server did not bind to a TCP port");
448
+ }
449
+ const port = address.port;
450
+ const baseUrl = `http://127.0.0.1:${port}`;
451
+ return {
452
+ port,
453
+ baseUrl,
454
+ seedFile(filePath, data) {
455
+ const normalizedPath = normalizeVfsPath(filePath);
456
+ storage.set(normalizedPath, {
457
+ path: normalizedPath,
458
+ content: data.content,
459
+ contentType: data.contentType ?? "application/json",
460
+ encoding: data.encoding ?? "utf-8",
461
+ revision: data.revision ?? randomRevision(),
462
+ provider: data.provider,
463
+ providerObjectId: data.providerObjectId,
464
+ lastEditedAt: data.lastEditedAt,
465
+ properties: data.properties ? { ...data.properties } : undefined,
466
+ asOf: data.asOf ?? Date.now(),
467
+ });
468
+ },
469
+ setResponse(filePath, override) {
470
+ overrides.set(normalizeVfsPath(filePath), { ...override });
471
+ },
472
+ clear() {
473
+ storage.clear();
474
+ overrides.clear();
475
+ requestLog.length = 0;
476
+ },
477
+ getRequestLog() {
478
+ return requestLog.map(cloneRequestLogEntry);
479
+ },
480
+ async close() {
481
+ if (closed) {
482
+ return;
483
+ }
484
+ closed = true;
485
+ await closeServer(server, sockets);
486
+ },
487
+ };
488
+ }
@@ -1,5 +1,5 @@
1
1
  const HEALTH_ENDPOINT = "/api/health";
2
- const SLACK_PROXY_ENDPOINT = "/api/v1/proxy/slack";
2
+ const SLACK_PROXY_ENDPOINT = "/cloud/api/v1/proxy/slack";
3
3
  const REQUEST_TIMEOUT_MS = 30_000;
4
4
  const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
5
5
  const SLACK_TEAM_ID_PATTERN = /^[TE][A-Z0-9]{6,}$/;
@@ -37,5 +37,5 @@ export function error(message, source) {
37
37
  };
38
38
  }
39
39
  export function isFresh(envelope, maxAgeMs = DEFAULT_FRESHNESS_MAX_AGE_MS) {
40
- return envelope.status === "hit" && envelope.ageMs <= maxAgeMs;
40
+ return envelope.status === "hit" && envelope.ageMs < maxAgeMs;
41
41
  }
@@ -6,23 +6,46 @@
6
6
  * Uses the workspace-resolved provider config key for repo access.
7
7
  */
8
8
  import { NangoClient } from '../nango.js';
9
+ import type { RecentActionsOverlay } from './recent-actions-overlay.js';
9
10
  import type { IntegrationResult, GitHubFile, GitHubIssue, GitHubPR, GitHubSearchResult } from './types.js';
11
+ type GitHubCreatedResource = {
12
+ id: number;
13
+ url: string;
14
+ };
15
+ type GitHubReviewEvent = 'APPROVE' | 'REQUEST_CHANGES' | 'COMMENT';
16
+ type GitHubPRCommentOptions = {
17
+ commitId?: string;
18
+ path?: string;
19
+ position?: number;
20
+ line?: number;
21
+ side?: 'LEFT' | 'RIGHT';
22
+ startLine?: number;
23
+ startSide?: 'LEFT' | 'RIGHT';
24
+ subjectType?: 'line' | 'file';
25
+ };
10
26
  export declare class GitHubIntegration {
11
27
  private readonly nango;
12
28
  private readonly connectionId;
13
29
  private readonly providerConfigKey;
14
- constructor({ nangoClient, connectionId, providerConfigKey, }: {
30
+ private readonly overlay;
31
+ constructor({ nangoClient, connectionId, providerConfigKey, overlay, }: {
15
32
  nangoClient: NangoClient;
16
33
  connectionId: string;
17
34
  providerConfigKey?: string | null;
35
+ overlay?: RecentActionsOverlay | null;
18
36
  });
19
37
  private errorResult;
20
38
  private execute;
39
+ private recordOverlay;
21
40
  searchCode(query: string, repo?: string): Promise<IntegrationResult<GitHubSearchResult>>;
22
41
  searchIssues(query: string, repo?: string): Promise<IntegrationResult<GitHubIssue[]>>;
23
42
  readFile(owner: string, repo: string, path: string, ref?: string): Promise<IntegrationResult<GitHubFile>>;
24
43
  readPRDiff(owner: string, repo: string, number: number): Promise<IntegrationResult<GitHubPR>>;
25
44
  listRepoFiles(owner: string, repo: string, path?: string): Promise<IntegrationResult<string[]>>;
26
45
  getIssue(owner: string, repo: string, number: number): Promise<IntegrationResult<GitHubIssue>>;
46
+ createIssueComment(owner: string, repo: string, number: number, body: string): Promise<IntegrationResult<GitHubCreatedResource>>;
47
+ createPRComment(owner: string, repo: string, number: number, body: string, options?: GitHubPRCommentOptions): Promise<IntegrationResult<GitHubCreatedResource>>;
48
+ createPRReview(owner: string, repo: string, number: number, body: string, event?: GitHubReviewEvent): Promise<IntegrationResult<GitHubCreatedResource>>;
27
49
  }
50
+ export {};
28
51
  //# sourceMappingURL=github.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../src/integrations/github.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,WAAW,EAAc,MAAM,aAAa,CAAC;AACtD,OAAO,KAAK,EACV,iBAAiB,EACjB,UAAU,EACV,WAAW,EACX,QAAQ,EACR,kBAAkB,EACnB,MAAM,YAAY,CAAC;AA4EpB,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAc;IACpC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;gBAE/B,EACV,WAAW,EACX,YAAY,EACZ,iBAAiB,GAClB,EAAE;QACD,WAAW,EAAE,WAAW,CAAC;QACzB,YAAY,EAAE,MAAM,CAAC;QACrB,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KACnC;IAWD,OAAO,CAAC,WAAW;YAOL,OAAO;IAcf,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;IAmCxF,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,WAAW,EAAE,CAAC,CAAC;IAmCrF,QAAQ,CACZ,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;IAmCnC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAuC7F,aAAa,CACjB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,iBAAiB,CAAC,MAAM,EAAE,CAAC,CAAC;IAmBjC,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;CA+BrG"}
1
+ {"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../src/integrations/github.ts"],"names":[],"mappings":"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"}